perm filename LISP.WD[S,DOC] blob sn#202031 filedate 1976-02-17 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00108 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00016 00002
C00017 00003	STANFORD ARTIFICIAL INTELLIGENCE LABORATORY
C00019 00004	SAILON 28.7 LISP                                                    i
C00020 00005	SAILON 28.7 LISP                                                   ii
C00022 00006	SAILON 28.7 LISP                                                  iii
C00026 00007	SAILON 28.7 LISP                                                   iv
C00030 00008	SAILON 28.7 LISP                                                    v
C00032 00009	SAILON 28.7                    CHAPTER 1                          1-1
C00035 00010	SAILON 28.7                    CHAPTER 1                          1-2
C00038 00011	SAILON 28.7                    CHAPTER 1                          1-3
C00041 00012	SAILON 28.7               Document Conventions                  1.4-1
C00044 00013	SAILON 28.7               Document Conventions                  1.4-2
C00045 00014	SAILON 28.7                    CHAPTER 2                          2-1
C00048 00015	SAILON 28.7                    CHAPTER 2                          2-2
C00050 00016	SAILON 28.7                    CHAPTER 3                          3-1
C00053 00017	SAILON 28.7                    CHAPTER 3                          3-2
C00056 00018	SAILON 28.7                    CHAPTER 3                          3-3
C00060 00019	SAILON 28.7                    CHAPTER 3                          3-4
C00061 00020	SAILON 28.7                    CHAPTER 4                          4-1
C00064 00021	SAILON 28.7                    CHAPTER 4                          4-2
C00067 00022	SAILON 28.7                    CHAPTER 4                          4-3
C00069 00023	SAILON 28.7                    CHAPTER 5                          5-1
C00071 00024	SAILON 28.7                    CHAPTER 6                          6-1
C00075 00025	SAILON 28.7                    CHAPTER 6                          6-2
C00078 00026	SAILON 28.7                    CHAPTER 6                          6-3
C00081 00027	SAILON 28.7                    CHAPTER 6                          6-4
C00083 00028	SAILON 28.7                    CHAPTER 7                          7-1
C00086 00029	SAILON 28.7                    CHAPTER 7                          7-2
C00089 00030	SAILON 28.7                    CHAPTER 7                          7-3
C00093 00031	SAILON 28.7                    CHAPTER 7                          7-4
C00097 00032	SAILON 28.7                    CHAPTER 8                          8-1
C00099 00033	SAILON 28.7                    CHAPTER 9                          9-1
C00102 00034	SAILON 28.7                    CHAPTER 9                          9-2
C00105 00035	SAILON 28.7                    CHAPTER 9                          9-3
C00108 00036	SAILON 28.7                    CHAPTER 10                        10-1
C00111 00037	SAILON 28.7                    CHAPTER 10                        10-2
C00114 00038	SAILON 28.7                    CHAPTER 10                        10-3
C00117 00039	SAILON 28.7                    CHAPTER 10                        10-4
C00120 00040	SAILON 28.7                    CHAPTER 10                        10-5
C00122 00041	SAILON 28.7                    CHAPTER 10                        10-6
C00125 00042	SAILON 28.7                    CHAPTER 10                        10-7
C00127 00043	SAILON 28.7                    CHAPTER 11                        11-1
C00131 00044	SAILON 28.7                    CHAPTER 11                        11-2
C00134 00045	SAILON 28.7                    CHAPTER 11                        11-3
C00136 00046	SAILON 28.7                    CHAPTER 12                        12-1
C00139 00047	SAILON 28.7                    CHAPTER 12                        12-2
C00141 00048	SAILON 28.7                    CHAPTER 12                        12-3
C00143 00049	SAILON 28.7                    CHAPTER 13                        13-1
C00146 00050	SAILON 28.7                    CHAPTER 14                        14-1
C00150 00051	SAILON 28.7                    CHAPTER 14                        14-2
C00154 00052	SAILON 28.7                    CHAPTER 14                        14-3
C00158 00053	SAILON 28.7                    CHAPTER 14                        14-4
C00161 00054	SAILON 28.7                    CHAPTER 14                        14-5
C00164 00055	SAILON 28.7                    CHAPTER 14                        14-6
C00166 00056	SAILON 28.7                    CHAPTER 15                        15-1
C00169 00057	SAILON 28.7                    CHAPTER 15                        15-2
C00172 00058	SAILON 28.7                    CHAPTER 16                        16-1
C00175 00059	SAILON 28.7                    CHAPTER 16                        16-2
C00178 00060	SAILON 28.7                    APPENDIX A                         A-1
C00182 00061	SAILON 28.7                    APPENDIX A                         A-2
C00185 00062	SAILON 28.7                    APPENDIX A                         A-3
C00188 00063	SAILON 28.7                    APPENDIX A                         A-4
C00191 00064	SAILON 28.7                    APPENDIX A                         A-5
C00193 00065	SAILON 28.7                    APPENDIX A                         A-6
C00195 00066	SAILON 28.7                    APPENDIX B                         B-1
C00198 00067	SAILON 28.7                    APPENDIX B                         B-2
C00201 00068	SAILON 28.7                    APPENDIX B                         B-3
C00204 00069	SAILON 28.7                    APPENDIX B                         B-4
C00206 00070	SAILON 28.7                    APPENDIX C                         C-1
C00209 00071	SAILON 28.7                    APPENDIX C                         C-2
C00212 00072	SAILON 28.7                    APPENDIX C                         C-3
C00214 00073	SAILON 28.7                    APPENDIX D                         D-1
C00217 00074	SAILON 28.7                    APPENDIX E                         E-1
C00220 00075	SAILON 28.7                    APPENDIX E                         E-2
C00223 00076	SAILON 28.7                    APPENDIX E                         E-3
C00227 00077	SAILON 28.7                    APPENDIX E                         E-4
C00229 00078	SAILON 28.7                    APPENDIX F                         F-1
C00233 00079	SAILON 28.7                    APPENDIX F                         F-2
C00237 00080	SAILON 28.7                    APPENDIX F                         F-3
C00241 00081	SAILON 28.7                    APPENDIX F                         F-4
C00244 00082	SAILON 28.7                    APPENDIX F                         F-5
C00246 00083	SAILON 28.7                    APPENDIX G                         G-1
C00249 00084	SAILON 28.7                    APPENDIX G                         G-2
C00250 00085	SAILON 28.7                    APPENDIX H                         H-1
C00254 00086	SAILON 28.7                    APPENDIX H                         H-2
C00257 00087	SAILON 28.7                    APPENDIX H                         H-3
C00258 00088	SAILON 28.7                    APPENDIX I                         I-1
C00260 00089	SAILON 28.7                    APPENDIX J                         J-1
C00264 00090	SAILON 28.7                    APPENDIX J                         J-2
C00267 00091	SAILON 28.7                    APPENDIX J                         J-3
C00269 00092	SAILON 28.7                    APPENDIX K                         K-1
C00273 00093	SAILON 28.7                    APPENDIX L                         L-1
C00276 00094	SAILON 28.7                    APPENDIX M                         M-1
C00279 00095	SAILON 28.7                    APPENDIX M                         M-2
C00281 00096	SAILON 28.7                    APPENDIX N                         N-1
C00284 00097	SAILON 28.7                    APPENDIX N                         N-2
C00285 00098	SAILON 28.7                    APPENDIX O                         O-1
C00288 00099	SAILON 28.7                    APPENDIX O                         O-2
C00290 00100	SAILON 28.7                    APPENDIX P                         P-1
C00292 00101	SAILON 28.7                    APPENDIX P                         P-2
C00294 00102	SAILON 28.7                    APPENDIX P                         P-3
C00296 00103	SAILON 28.7                    APPENDIX P                         P-4
C00297 00104	SAILON 28.7                    REFERENCES                       REF-1
C00298 00105	SAILON 28.7                      INDEX                          IND-1
C00303 00106	SAILON 28.7                      INDEX                          IND-2
C00308 00107	SAILON 28.7                      INDEX                          IND-3
C00313 00108	SAILON 28.7                      INDEX                          IND-4
C00317 ENDMK
C⊗;

STANFORD ARTIFICIAL INTELLIGENCE LABORATORY
OPERATING NOTE 28.7









                      STANFORD LISP 1.6 MANUAL

                                 by

                  Lynn H. Quam and Whitfield Diffie












ABSTRACT: This manual describes the PDP-10 LISP 1.6 system developed by
	  the Stanford Artificial Intelligence Project.   The manual is
	  not a tutorial on LISP but is intended to supplement existing
	  LISP  tutorials in order to prepare one to understand and use
	  this LISP system.












This work was supported by the Advanced Research Projects Agency of the
Department of Defense under Contract SD-183.

The views and conclusions contained in this document are those of the
authors and should not be interpreted as necessarily representing the
official policies, either  expressed  or  implied,  of  the  Advanced
Research Projects Agency or the U.S. Government.
SAILON 28.7 LISP                                                    i

                               PREFACE


	This manual is the result of several relatively minor changes
and  additions to SAILON 28.4.  It supercedes and replaces SAILONS 1,
4, 28.2-4, and 41.

	The changes reflect changes in LISP and may be summarized  as
follows:

	LISP initialization has changed; Section 2.1.

	There are some new debugging facilities in Appendix N and the
documentation for some old ones has been put into the manual.

	The  compiler has been revised, and is described in a greatly
expanded Appendix F.

SAILON 28.7 LISP                                                   ii

                           Acknowledgment

	The   STANFORD   A.I.  Lisp  1.6  System  was  originally  an
adaptation of one developed by the Artificial Intelligence Project at
M.I.T.   Since  1966,  that system has been largely rewritten by John
Allen and Lynn Quam.

	John R.  Allen implemented the  storage  reallocation  system
which  makes  it  possible  for  the  user to change the sizes of the
various memory spaces.  He also designed and coded the editor ALVINE,
wrote  the  first  loader  interface,  and  generally  maintained and
debugged  the   system.     John   Allen   contributed   the   ALVINE
documentation in Appendix A.

	Marilyn  Mullins  has  assisted  in  the  preparation  of the
present edition.
SAILON 28.7 LISP                                                  iii

                          TABLE OF CONTENTS
							Page
Preface.................................................   i
Acknowledgment .........................................  ii
Table of Contents....................................... iii

CHAPTER

  1.  INTRODUCTION...................................... 1-1

      1.1 Guide to the Novice........................... 1-1
      1.2 Guide to the User Experienced with Another        
		LISP System............................. 1-2
      1.1 Guide to Useful Functions and Features........ 1-3
      1.4 Document Conventions.......................... 1-4

  2.  INTERACTIVE USE OF THE SYSTEM .................... 2-1

      2.1 Using the System ............................. 2-1
      2.2 Special Teletype Control Characters........... 2-1

  3.  IDENTIFIERS ...................................... 3-1

      3.1 Property Lists................................ 3-2
      3.2 The OBLIST.................................... 3-3
      3.3 Strings....................................... 3-3

  4. NUMBERS............................................ 4-1

      4.1 Integers...................................... 4-1
      4.2 Reals......................................... 4-3

  5. S-EXPRESSIONS...................................... 5-1

  6. LAMBDA EXPRESSIONS................................. 6-1

      6.1 EXPRs and SUBRs............................... 6-2
      6.2 FEXPRs AND FSUBRs............................. 6-2
      6.3 LEXPRs AND LSUBRs............................. 6-2
      6.4 MACROs........................................ 6-3

  7. EVALUATION OF S-EXPRESSIONS........................ 7-1

      7.1 Variable Bindings............................. 7-2
      7.2 The A-LIST and FUNARG Features................ 7-3

  8. CONDITIONAL EXPRESSIONS............................ 8-1
SAILON 28.7 LISP                                                   iv

  9. PREDICATES......................................... 9-1

      9.1 S-Expression Predicates....................... 9-2
      9.2 Numerical Predicates.......................... 9-2
      9.3 Boolean Predicates............................ 9-3

 10. FUNCTIONS ON S-EXPRESSIONS.........................10-1

     10.1 S-Expression Building Functions...............10-1
     10.2 S-Expression Fragmenting Functions............10-2
     10.3 S-Expression Modifying  Functions.............10-2
     10.4 S-Expression Transforming Functions...........10-4
     10.5 S-Expression Mapping Functions................10-4
     10.6 S-Expression Searching Functions..............10-6
     10.7 Character List Transforming Functions.........10-7

 11. FUNCTIONS ON IDENTIFIERS...........................11-1

     11.1 Property List Functions.......................11-1
     11.2 OBLIST Functions..............................11-2
     11.3 Identifier Creating Functions.................11-3

 12. FUNCTIONS ON NUMBERS...............................12-1

     12.1 Arithmetic Functions..........................12-1
     12.2 Logical Functions.............................12-2

 13. PROGRAMS...........................................13-1

 14. INPUT/OUTPUT.......................................14-1

     14.1 File Names....................................14-1
     14.2 Channel Names.................................14-1
     14.3 Input.........................................14-1
     14.4 Output........................................14-4

 15. ARRAYS.............................................15-1

     15.1 Examine and Deposit...........................15-2

 16. OTHER FUNCTIONS....................................16-1

APPENDIX A.  ALVINE - by John Allen..................... A-1
APPENDIX B.  ERROR MESSAGES............................. B-1
APPENDIX C.  MEMORY ALLOCATION.......................... C-1
APPENDIX D.  GARBAGE COLLECTION......................... D-1
APPENDIX E.  COMPILED FUNCTION LINKAGE AND ACCUMULATOR      
		USAGE................................... E-1
APPENDIX F.  THE LISP COMPILER.......................... F-1
APPENDIX G.  THE LISP ASSEMBLER - LAP................... G-1
APPENDIX H.  THE LOADER................................. H-1
APPENDIX I.  BIGNUMS - ARBITRARY PRECISION INTEGERS..... I-1
SAILON 28.7 LISP                                                    v

APPENDIX J.  A USER MODIFIABLE LISP SCANNER............. J-1
APPENDIX K.  SOS-LINK................................... K-1
APPENDIX L.  SOME DIFFERENCES BETWEEN THIS AND OTHER 
		LISPS................................... L-1
APPENDIX M,  LISP DISPLAY PRIMITIVES.................... M-1
APPENDIX N.  TRACE...................................... N-1
APPENDIX O.  SMILE ..................................... O-1
APPENDIX P.  CONSTRUCTION OF A LISP DISK-DECTAPE SYSTEM..P-1

REFERENCES.............................................REF-1
INDEX..................................................IND-1
SAILON 28.7                    CHAPTER 1                          1-1

                              CHAPTER 1

                            INTRODUCTION

	This manual is intended to explain the interactive  LISP  1.6
system  which  has  been  developed  for  the  PDP-10 at the Stanford
University Artificial Intelligence Project.  It is assumed  that  the
reader is familiar with either some other LISP system or the LISP 1.5
PRIMER by Clark Weissman[2].

	The LISP 1.6 system described has as a  subset  most  of  the
features and functions of other LISP 1.5 systems.  In addition, there
are several new features  such  as  an  arbitrary  precision  integer
package,  an  S-expression  editor,  up  to  14  active  input-output
channels, the ability  to  control  the  size  of  memory  spaces,  a
standard  relocating  loader  to  load  assembly language or compiled
programs, etc.

	This system uses an interpreter; however,  there  is  also  a
compiler   which  produces  machine  code.   Compiled  functions  are
approximately 20 times as fast and take less memory space.

	This manual is organized in a functional manner.   First  the
basic data structures are described; then the functions for operating
on them. The appendices present  more  detailed  information  on  the
system,  its  internal structure, the compiler, and several auxiliary
packages.
SAILON 28.7                    CHAPTER 1                          1-2

1.1  Guide to the Novice 

	The user who is not  experienced  with  any  LISP  system  is
advised to follow the instructions below:

	1) Become familiar with Weissman's LISP 1.6 Primer[2] or some
	   equivalent introductory LISP Manual.

	2)  Learn the document conventions (1.4).

	3) Become superficially familiar with LISP  1.6  identifiers,
	   numbers and S-expressions (Chapters 3,4, and 5).

	4) Understand the most useful functions:  Those  preceded  by
	   exclamation marks "!" in chapters 6 through 14.

	5) Learn how to define functions (6.1).

	6)  Learn how to interact with LISP (Chapter 2).

	7)  Try some examples.  Weissman[1] has some good problems.

	8)  Learn  what  other  useful  functions  and  features  are
	   available (1.3).

1.2  Guide to the User Experienced with Another LISP System

	The user who has used  another  LISP  system  is  advised  to
	   follow these instructions:

	1)  Learn the document conventions (1.4).

	2)  Learn top level of LISP 1.6 is EVAL, not EVALQUOTE.

	3) Use DE, DF and DEFPROP for defining functions.  (Section 11.1).

	4) Many functions differ from those in other  systems.   Most
	   of these are noted in the index.

	5) The syntax  of  atoms  is  different  from  other  systems
	   (Chapters 3 and 4).

	6)  Learn how to interact with LISP (Chapter 2).

	7)  Try some examples.

	8)  Learn  what  other  useful  functions  and  features  are
	   available (1.3).
SAILON 28.7                    CHAPTER 1                          1-3

1.3  Guide to Useful Functions and Features



The following is a partial list of useful features and  functions  in
LISP 1.6 and what they might be useful for.

     1)  ALVINE (Appendix A) is useful for editing functions and
	 manipulating I/O files.

     2)  READ has some very useful control characters (Section 14.3).

     3)  Input/Output (Chapter 14) is very flexible.

     4)  One can control error messages (Chapter 16).

     5)  There is a LISP compiler (Appendix F) which generates code
	 that runs approximately twenty times as fast as interpreted
	 functions.

     6) There are auxiliary files on the disk which are often useful:

	filename 		use 			document 

	SYS:SMILE 		file manipulation 	Appendix  O

	SYS:TRACE 		tracing functions 	Appendix  N
				and setqs 

	SYS:SOSLNK 		rapid turn-around 	Appendix  K
				between SOS and LISP 

	SYS:LISPDP.LSP		III display functions 	Appendix  M

	LISP.COR[S,DOC]		corrections to this 
				manual 

   7)   One can load and link LISP to assembly and Fortran 
	compiled programs.  See Appendix H.

   8)   One can have files automatically loaded by use of 
	the file INIT.LSP which is automatically loaded 
	on entry. 

SAILON 28.7               Document Conventions                  1.4-1

1.4  Document Conventions

1.4.1  Representation Conventions

	In  the  description  of  data  structures,   the   following
notational conventions will be used.

  _________________			represents a 36-bit word in
  |       |       |			FREE STORAGE with 2 18-bit
  |       |       |-→			pointers.
  |_______|_______|  			         

      ↓

  _________________			represents the last word in
  |       |       |			a list.
  |       |  NIL  | →
  |_______|_______|

      ↓

  _________________			represents a 36-bit word in
  |               |			FULL WORD SPACE.
  |               |
  |_______________|

1.4.2  Syntax Conventions

	A slightly modified form of BNF  is  used  to  define  syntax
equations. Optional terms are surrounded by curly brackets { and }.

1.4.3  Calling Sequence Conventions

	Calling  sequences  to  LISP  functions  are   presented   in
S-expression form, with the CAR of the S-expression being the name of
the function. An argument to a  function  is  evaluated  unless  that
argument  is  surrounded  by  quotes  (")  in  the  calling  sequence
definition.  Quotes mean that the  function  implicitly  QUOTEs  that
argument.

Examples:	(SETQ "ID" V)		ID is not evaluated, but V is
					evaluated.

		(QUOTE "V")		V is not evaluated.

1.4.4  Other Conventions

	The blank character (ASCII  40)  is  indicated  by  "_"  when
appropriate  for  clarity.  The  delimiters altmode, carriage return,
linefeed and space will sometimes be represented as <alt>, <cr>, <lf>
and <sp>.
SAILON 28.7               Document Conventions                  1.4-2

	A special notation in the left margin is used to indicate the
degree of utility or difficulty of each section of this manual:

	mark		meaning
	!		basic
	<no mark>	generally useful
	*		useful but more sophisticated
	#		not generally useful
SAILON 28.7                    CHAPTER 2                          2-1

                              CHAPTER 2

                    INTERACTIVE USE OF THE SYSTEM

2.1  Using the System

	The  following  dialog shows how to log into the time sharing
system, start the LISP system, and interact with  the  top  level  of
LISP.  The  period,  sharp sign and askerisk are typed by the system,
login and lisp respectively to indicate that they are waiting for the
user to type.

.L 
#1,FOO 
↑C 

.R LISP 20		This give a 20K Lisp instead of the usual 12K.
ALLOC? Y		Indicates that the user will specify
			the sizes of the various spaces.
FULL WDS=<sp>		This gives the default value.
BIN.PROG.SP=12000<sp>	This gives 12K of Binary Program Space.
SPEC.PDL=<sp>		This give the default value.
SPEC.PDL=2000<sp>	Gives 2K of regular push down list.
HASH=177<sp>		Makes the length of the OBLIST 177.

	For a full discussion of allocation see Appendix C. 

Digression: 

	At this point, after allocation and before anything else, the
file LISP.LSP is read from the system.  This defines  various macros,
recent  additions  to  the  system,  bootstrap  definitions  for  the
functions  in  the various self loading utility files, Trace, SOSLNK,
LAP etc.  In addition, if there is a file by the name LISP.INI in the
user's  directory,  it  will be loaded too.  This enables the user to
have anything he likes loaded automatically.

To continue: 

*T<alt> 
T 		T and NIL always evaluate to themselves. 
*(QUOTE (A B C))<cr>
(A B C) 		Value of QUOTE 
*(CONS 1 (QUOTE A))<cr> 

(1 . A) 		Numbers always evaluate to themselves 
			and thus need not be quoted.  

*(DSKIN <random file name>)<cr>	Reads and evaluates each expression
				in the file.

<a long sequence of output> 	This output can be suppressed with ↑O. 
SAILON 28.7                    CHAPTER 2                          2-2

*(DEFPROP CDRQ (LAMBDA (L) (CDAR L)) FEXPR)<cr> 

CDRQ 

*(CDRQ CAR)<cr> 

(SUBR #address PNAME (#fullword)) 

*(DE TWICE (NUM) (TIMES 2 NUM))<cr> 

TWICE 

*(TWICE 3)<cr> 

6 

<etc.> 

2.2  Special Teletype Control Characters

The  time-sharing  system  treats  many control characters in special
ways.  For a complete discussion of control characters see the PDP-10
TIME  SHARING MONITOR MANUAL.  Briefly, the following special control
characters are used in LISP.

     Teletype		III Display		Meaning

	↑C		  CALL		Stop the job and talk to
					time-sharing system.

	↑O		Control 2	Suppress console printout
			linefeed	until an input is requested.

	↑U		Control 1	Delete the entire input
			linefeed	line now being typed.
					(Only with (DDTIN NIL)).

	↑G(BELL)	   π		Stop the LISP interpreter
					and return control to the
					top level of LISP.  Only
					effective when LISP is 
					asking for console input.
					See INITFN (16).

	rubout		   BS		Delete the last character
					typed.  (For (DDTIN T) see
					14-3.
SAILON 28.7                    CHAPTER 3                          3-1

                              CHAPTER 3

                             IDENTIFIERS

	Identifiers are strings of characters  which  taken  together
represent a single atomic quantity.

	Syntax:

	<comments>  ::=<ASCII 32> <any  sequence  of  characters  not 
			including line-feed> <line feed>
	<delimiter>  ::= (|) | [|] | ? |@|/|"| <blank> | <altmode> | 
			carriage-return | <line-feed> | <tab> | <form-
			feed>
	<character>::= <any extended ASCII character other than null 
			and ASCII 176>
	<digit>::= 0|1|2|3|4|5|6|7|8|9
	<letter>::= <any character not a digit and not a delimiter>
	<identifier>::= <letter>
		    ::=<identifier> <digit>
		    ::= / <character>
		    ::= <identifier>/<character>

	Semantics:

	Identifiers are normally strings of characters beginning with
a letter and  followed  by  letters  and  digits.   It  is  sometimes
convenient  to  create  identifiers which contain delimiters or begin
with digits.  The  use  of  the  delimiter  "/"  (slash)  causes  the
following  character  be taken literally, and the slash itself is not
part of the identifier.  Thus, /AB is the same as AB is the  same  as
/A/B.

	Comments  are  useful  for allowing descriptive text in files
which will be completely ignored when read.  Comments  also  make  it
possible  to  extend  atoms (identifiers, strings and numbers) across
line boundaries without any of the characters in the comment becoming
part of the atom.

	ASCII  32 cannot be typed directly into LISP.  In STOPGAP, ?3
designates ASCII 32.  On the line printer and III displays, ASCII  32
prints  as  tilde  "~".  ASCII  32 does not print on teletypes.  (See
CHRCT in 14.1.4.)

Examples:	A			/(
		a			?
		FOObaz			/13245
		TIME-OF-DAY		/,
		A1B2			LPT:

	Representation:
SAILON 28.7                    CHAPTER 3                          3-2

	An identifier is internally represented as a dotted  pair  of
the following form:

		      ___________
	identifier  → | -1 |    | → property list
		      |____|____|

which is called an atom header.

	Thus  CDR  of  an  identifier  gives the property list of the
identifier, but CAR of an identifier gives the pointer 777777,  which
if  used as an address will cause an illegal memory reference, and an
error message.  An identifier is referred to in symbolic  computation
by the address of its atom header.

3.1   Property Lists

	The property list of  an  identifier  is  a  list  of  pairs:
(property name, property value) associated with that identifier.  The
normal kinds of properties which are  found  in  property  lists  are
print  names,  values,  and  function  definitions  corresponding  to
identifiers.

3.1.1  Print Names

	Every  identifier  has  a  print name (PNAME) on its property
list.   The print name of an identifier is a list of full words, each
containing five ASCII characters.

Example:   The identifier TIME-OF-DAY would be initially  represented
as follows:

        __________   _________   _________
atom  → | -1 |   | → |   |   | → |   |NIL|
header  |____|___|   |___|___|   |___|___|

		       ↓	   ↓
				 _________   _________   _________
		      atom	 |   |   |   |   |   |   |   |NIL|
		     "PNAME"	 |___|___|   |___|___|   |___|___|

				   ↓	       ↓	   ↓
				 _________   _________   _________
				 | TIME- |   | OF-DA |   | Y∧∧∧∧ |
				 |_______|   |_______|   |_______|
					   
where ∧ means null or ASCII 0.
SAILON 28.7                    CHAPTER 3                          3-3

3.1.2  Special Cells

	When a value is assigned an  identifier,  the  property  name
VALUE  is  put  on the identifier's property list with property value
being a pointer to a special cell.   The  CDR  of  the  special  cell
(sometimes  called VALUE cell) holds the value of the identifier, and
the address of a special cell remains constant  for  that  identifier
unless  REMPROPed  (11.2),  to  enable compiled functions to directly
reference the values of special variables.  Global variables and  all
variables  bound  in  interpreted  functions  store  their  values in
special cells.

Example:  The atom NIL has the following form:

	atom header	property list
             _________ __________ _________ __________ _________
	     | -1|   |→|VALUE|  |→|   |   |→|PNAME|  |→|   |NIL|
	     |___|___| |_____|__| |___|___| |_____|__| |___|___|

	       ↑		    ↓			 ↓
	       |     special      _________            _________
               |      cell        |NIL|NIL|     print  |   |NIL|
               |                  |___|___|     name   |___|___|
	       |________________________|
							 ↓
                                                       _________
                                                       | NIL∧∧ |
						       |_______|

3.2 The OBLIST

	In  order that occurrences of identifiers with the same print
names have the same internal address (and  hence  value),  a  special
list which is the VALUE of a global variable called OBLIST is used to
remember all identifiers which READ and  some  other  functions  have
seen.   For  the  sake  of  searching  efficiency,  this list has two
levels; the first level contains sequentially stored "buckets"  which
are  "hashed" into as a function of the print name of the identifier.
Each bucket is a list of all distinct identifiers which  have  hashed
into  that bucket.  Thus, (CAR OBLIST) is the first bucket, and (CAAR
OBLIST) is the first identifier of the first bucket.

3.3  Strings

	Syntax:
	   
	   string::= "<any sequence of characters not containing ">"

	Semantics
SAILON 28.7                    CHAPTER 3                          3-4

	A string is an arbitrary sequence of characters surrounded by
double  quotes  and  not  containing  double  quotes.   Strings   are
represented  identically  to  identifiers except that strings are not
automatically INTERNed on the OBLIST.  The double quotes  surrounding
strings  actually  become part of the PRINT NAME of the string unlike
slashes in slashified identifiers.

	Examples:

	   "I AM A STRING"
	   "1,3-X 5"

SAILON 28.7                    CHAPTER 4                          4-1

                              CHAPTER 4

                               NUMBERS

	There are two syntactic types of numbers:  integer and real.

		<number>	::= <integer> | <real>

4.1  Integers

	Syntax:

	  <integer>	::= {<sign>} <digits> {*}

	  <digits>	::= <digit> {<digits>}

	  <sign>	::=  +|-

	Semantics:

	The  global  variable  IBASE  specifies  the  input radix for
integers which are not followed by "." Integers followed by  "."  are
decimal  integers.   IBASE  is  initially = 8.  Similarly, the global
variable BASE controls output radix for integers.  If BASE = 10  then
integers  will print with a following ".", unless the global variable
*NOPOINT = T.

	Examples with IBASE = 8

		input		meaning

		-13  =   -11	= -11↓10
	       1000  =   512    =+512↓10
		 19  =    17    = +17↓10

	Representation:

	There are three representations for integers depending on the
numerical magnitude of the integer:  INUM, FIXNUM, and BIGNUM.  Their
ranges are as follows:

	INUM		|n|  <K		K is usually 2↑16

	FIXNUM	   K≤   |n| <2↑35

	BIGNUM	 2↑35 ≤ |n|

Representation of INUMs:

	INUMs are small integers represented by pointers  outside  of
the  normal  LISP addressing space.  INUMs are addresses in the range
2↑18-2K to 2↑18-2.  The INUM representation for zero is α = 2↑18-K-1.
SAILON 28.7                    CHAPTER 4                          4-2

Examples		INUM		Representation

			-(K-1)		α - (K-1)
			-1		α - 1
			 0		α = 2↑18-K-1
			 1		α + 1
			 K-1		α + K-1

Representation of FIXNUMs:

	FIXNUMs are represented by list structure of the following form:

		Atom header
		    ________   ___________   _________
		    | -1|  |→  |FIXNUM|   |→ | value |
		    |___|__|   |______|___|  |_______|

where  value  is the 2's complement representation of the fixed point
number.

Examples:

			    ________   ___________   _____________
         +100000000↓8       | -1|  |→  |FIXNUM|   |→ |000100000000|
		     	    |___|__|   |______|___|  |____________|

			    ________   ___________   _____________
        -1400000032↓8       | -1|  |→  |FIXNUM|   |→ |776377777746|
		     	    |___|__|   |______|___|  |____________|

Representation of BIGNUMs

	BIGNUMs are represented by list structure of the following forms:

			    ________   ___________   _________  _________
Positive BIGNUMs          → | -1|  |→  |POSNUM|   |→ |   |   |→ |   |NIL|
		     	    |___|__|   |______|___|  |___|___|  |___|___|
						       ↓          ↓
			                             _________  _________
                                                     | N0    |  | Nn    |
                                                     |_______|  |_______|


			    ________   ___________   _________  _________
Negative BIGNUMs          → | -1|  |→  |NEGNUM|   |→ |   |   |→ |   |NIL
		     	    |___|__|   |______|___|  |___|___|  |___|___|
						       ↓          ↓
			                             _________  _________
                                                     | N0    |  | Nn    |
                                                     |_______|  |_______|

SAILON 28.7                    CHAPTER 4                          4-3

where N↓i are positive 36 bit integers ordered  from  least  to  most
significant.  The value of a BIGNUM is

	sign * (N↓0 + 2↑35 N, + 2↑35*2 N↓2 + ... + 2↑35n N↓n)

Note:  BIGNUMs are not normally a part of the interpreter.  Appendix H
       describes the procedures for loading the BIGNUM package.

4.2  Reals

Syntax:

	<real>		::= {<sign>}  <digits> {*} <exponent>
			::= {<sign>} {<digits>} *  <digits> {<exponent>}
	<exponent>	::= E {<sign>}  <digits>

Examples:

			meaning
	3.14159		+3.14159
	+1E-3		+0.001
	-196.37E4	-1963700.0
	0.3		+0.3
	-0.3E+1		-3.0

Restrictions:

	The radix for real numbers is always decimal. A real number x
must be in the (approximate) range:

		10↑-38  < |x|  <  10↑+38   or x = 0

A real number has approximately eight significant digits of accuracy.

Representation:

	atom header
       __________     _______________     _________
       | -1 |   |  →  |FLONUM|      |  →  | value |
       |____|___|     |______|______|     |_______|

where  value  is  in   PDP-6/10   2's   complement   floating   point
representation.
SAILON 28.7                    CHAPTER 5                          5-1

                              CHAPTER 5

                            S-EXPRESSIONS


Syntax:

	<atom> ::= <identifier> | <string> | <number>

	<S-expression> ::= <atom>
		       ::= (<S-expression list>{*<S-expression>})
		       ::= ( )			= NIL
	<S-expression list>  ::= <S-expression>
			     ::= <S-expression>  <S-expression list>

Representation:

	S-expression		representation
				_________
	(A . (B . C))	      → | A |   |
				|___|___|

				      ↓
				    _________
				    | B | C |
				    |___|___|


				_________   _________   _________	
	((A . B) (C . D) E)   → |   |   | → |   |   | → | E |NIL|
				|___|___|   |___|___|   |___|___|

				  ↓	      ↓
				_________   _________  
				| A | B |   | C | D |                     
				|___|___|   |___|___| 


				_________   _________  	
	(A B . C)	      → | A |   | → | B | C |
				|___|___|   |___|___| 



Exceptions:

	The identifier NIL is the  identifier  which  represents  the
empty list, i.e., ().
SAILON 28.7                    CHAPTER 6                          6-1

                              CHAPTER 6

                         LAMBDA EXPRESSIONS


	LAMBDA   expressions   provide   the  means  of  constructing
computational procedures (often  called  functions,  subroutines,  or
procedures) which  compute  answers when values are assigned to their
parameters.  A LAMBDA expression can be bound  to  an  identifier  so
that any reference to that identifier in functional context refers to
the LAMBDA expression.  In  LISP  1.6  there  are  several  types  of
function  definition  which  determine how arguments are bound to the
LAMBDA expression.  The following is a LAMBDA expression:

!	(LAMBDA "ARGUMENT-LIST" "BODY")

	LAMBDA  defines  a  function  by specifying an ARGUMENT-LIST,
which is a list of identifiers (except for LEXPRs,  see  6.3)  and  a
BODY,  which is an S-expression.  LAMBDA expressions may have no more
than five arguments if they are to be compiled.

Examples:	(LAMBDA NIL 1)	
			This LAMBDA expression of no arguments always 
		evaluates to one.

		(LAMBDA (X) (TIMES X X))
			This LAMBDA expression computes the square of 
		its argument, if x is a number.  Otherwise  an error
		will result.

#	(LABEL "ID" "LAMBDA-EXPR")

	LABEL creates a temporary name ID for its LAMBDA  expression.
This   makes  it  possible  to  construct  recursive  functions  with
temporary names.

Example:

(DE REVERSE (L)
    ((LABEL REVEVSE1
	    (LAMBDA (L M)
		    (COND ((ATOM L) M)
			   (T (REVERSE1 (CDR L) (CONS (CAR L) M))))))
     L NIL))

	LAMBDA   expressions   are   evaluated  by  "binding"  actual
arguments to dummy variables of the LAMBDA expression,  (see  Chapter
14)  then  evaluating  the body inside the LAMBDA expression with the
current dummy variable bindings.  However, actual arguments to LAMBDA
expressions  are  handled in a variety of ways.  Normally, there is a
one-to-one  correspondence  between  dummy   variables   and   actual
arguments,  and  the  actual  arguments are evaluated before they are
SAILON 28.7                    CHAPTER 6                          6-2

bound.  However, there are three special forms of function definition
which differ in their handling of actual arguments.

! 6.1 EXPRs and SUBRs

	An EXPR is an identifier which has a LAMBDA expression on its
property  list  with  property  name  EXPR.   EXPRs  are evaluated by
binding the values of the actual  arguments  to  their  corresponding
dummy  variables.  DE  (see  11.1) is useful for defining EXPRs.  The
compiled form of an EXPR is a SUBR.

Examples:

	(DE SQUARE (X) (TIMES X X))
	(DE *MAX (X Y) (COND ((GREATERP X Y) X) (T Y)))

6.2  FEXPRs and FSUBRs

	A FEXPR is an identifier which has a LAMBDA expression of one
dummy variable on its property list with property name FEXPR.  FEXPRs
are  evaluated  by  binding  the  actual  argument  list to the dummy
variable without evaluating any arguments.  DF (see 11.1)  is  useful
for defining FEXPRs.  The compiled form of an FEXPR is an FSUBR.

Examples:

	(DF LISTQ (L) L)
		(LISTQ A (B) C) = (A (B) C)
		(LISTQ) = NIL
	(DF DEFINE (L)
		(MAPC (FUNCTION (LAMBDA (X) (PUTPROP (CAR X)
						     (CADR X)
						     (QUOTE EXPR))))
			L))
		(DEFINE (LEQ (LAMBDA (X Y) (OR (LESSP X Y)
					       (EQUAL X Y))))
			(GEQ (LAMBDA (X Y) (OR (GREATERP X Y)
					       (EQUAL X Y)))))

# 6.3  LEXPRs and LSUBRs

	An LEXPR is an EXPR whose LAMBDA  expression  has  an  atomic
argument "list" of the form:

	(LAMBDA "ID" "FORM")

LEXPRs may take an arbitrary number of  actual  arguments  which  are
evaluated  and  referred to by the special function ARG.  ID is bound
to the number of arguments which are passed.  The compiled form of an
LEXPR is an LSUBR.

(ARG N)
SAILON 28.7                    CHAPTER 6                          6-3

	ARG returns the value of the Nth argument to an LEXPR.

Example:

	(DE MAX N
	   (PROG (M)
		 (SETQ M (ARG N))
	       L (SETQ N (SUB1 N))
		 (COND ((ZEROP N) (RETURN M))
		       ((GREATERP (ARG N) M) (SETQ M (ARG N))))
		 (GO L)))
	(MAX 1 1.2 4 3 -50) = 4

(SETARG N V)

	SETARG sets the value of the Nth argument to V and returns V.

6.4 MACROs

	A MACRO is an identifier which has a LAMBDA expression of one
dummy variable on its property list with property name MACRO.  MACROs
are evaluated by binding the list containing the macro name  and  the
actual  argument  list to the dummy variable.  The body in the LAMBDA
expression is evaluated and should result in another "expanded" form.
In the interpreter, the expanded form is evaluated.  In the compiler,
the expanded form is compiled.  DM( see 11.1) is useful for  defining
MACROs.

Examples:

1)  We could define CONS of an arbitrary number of arguments by:

	(DM CONSCONS (L)
	    (COND ((NULL (CDDR L)) (CADR L))
		  (T (LIST (QUOTE CONS)
			   (CADR L)
		 	   (CONS (QUOTE CONSCONS) (CDDR L))))))

	(CONSCONS  A  B C) would call CONSCONS with L = (CONSCONS A B
C). CONSCONS then forms the list (CONS A(CONSCONS B C)).   Evaluating
this  will  again call CONSCONS with L = (CONSCONS C).  CONSCONS will
finally return C.

	The effect of (CONSCONS A B C) is then (CONS A (CONS B C)).

2)  We could define a function EXPAND which is more generally useful
for MACRO expansion:

	(DE EXPAND (L FN)
	    (COND ((NULL (CDR L)) (CAR L))
		  (T (LIST FN (CAR L) (EXPAND (CDR L) FN))))))
SAILON 28.7                    CHAPTER 6                          6-4

Then we could define CONSCONS:

	(DM CONSCONS (L) (EXPAND (CDR L) (QUOTE CONS)))

	It  should  be noted that MACROs are more general than FEXPRs
and LEXPRs.  In fact the previous definitions can be replaced by  the
following MACROs:

	(DM LISTQ (L) (LIST (QUOTE QUOTE) (CDR L))))
	(DM MAX (L) (EXPAND (CDR L) (QUOTE *MAX)))
		(MAX A B C D) would expand to:
		(*MAX A (*MAX B (*MAX C D)))

3)  (*EXPAND L FN)
    (*EXPAND1 L FN)

*EXPAND and *EXPAND1 are MACRO  expanding  functions  used  by  PLUS,
TIMES, etc.  They are equivalent to:

	(DE *EXPAND (L FN) (*EXPAND1 (REVERSE (CDR L)) FN))
	(DE *EXPAND1 (L FN)
	  (COND ((NULL (CDR L)) (CAR L))
	     (T (LIST FN (*EXPAND1 (CDR L) FN) (CAR L)))))

Example:

	With PLUS defined as

	(DM PLUS (L) (*EXPAND L(QUOTE *PLUS)))
	(PLUS A B C D) expands to:
	   (*PLUS (*PLUS (*PLUS A B) C) D)

SAILON 28.7                    CHAPTER 7                          7-1

                              CHAPTER 7

                     EVALUATION OF S-EXPRESSIONS

	This chapter describes the heart of the LISP interpreter, the
mechanism for evaluating S-expressions.

! (*EVAL E)
  (EVAL E)

	*EVAL  and  EVAL  (see  7.2)  evaluate  the  value   of   the
S-expression E.

Examples:

	(EVAL (LIST (QUOTE ADD1) 3)) = 4
The top level of LISP is:
	(PROG NIL
	 L    (PRINT (EVAL (READ))) (TERPRI) (GO L))

!  (APPLY FN ARGS)

	APPLY evaluates and binds each S-expression in  ARGS  to  the
corresponding  arguments of the function FN, and returns the value of
FN. See 7.2.

Example:

	(APPLY (FUNCTION APPEND) (QUOTE ((A B) (C D)))) = (A B C D)

! (QUOTE "E")

	QUOTE returns the S-expression E without evaluating it.

  (FUNCTION "FN")

	FUNCTION  is  the  same  as QUOTE in the interpreter.  In the
compiler, FUNCTION causes the S-expression FN  to  be  compiled,  but
QUOTE  generates  an S-expression constant.  See *FUNCTION in 7.2 for
the special FUNARG feature.

	The  following  function  definitions  lack  some details but
explain the essence of EVAL and APPLY.  The A-LIST feature  of  these
functions is not shown, but will be explained in 7.2.

(DE EVAL (X)
    (PROG (Y)
       (RETURN
	 (COND ((NUMBERP X) X)
	       ((ATOM X) (COND ((SETQ Y (GET X (QUOTE VALUE)))
				(CDR Y))
			       (T (ERR (QUOTE (UNBOUND VARIABLE)))))
SAILON 28.7                    CHAPTER 7                          7-2

		((ATOM (CAR X))
		 (COND ((SETQ Y (GETL (CAR X) (QUOTE EXPR FEXPR MACRO))))
				(COND ((EQ (CAR Y) (QUOTE EXPR))
				       (APPLY (CADR Y)
					      (MAPCAR (FUNCTION EVAL) (CDR X))))
				      ((EQ (CAR Y) (QUOTE FEXPR)
				       (APPLY (CADR Y) (LIST (CDR X))))
				      (T (EVAL (APPLY (CADR Y) (LIST X))))))
			      ((SETQ Y (GET (CAR X) (QUOTE VALUE)))
			       (EVAL (CONS (CDR Y) (CDR X))))
			      (T (ERR (QUOTE (UNDEFINED  FUNCTION))))))
			(T (APPLY (CAR X) (MAPCAR (FUNCTION EVAL) (CDR X))))))))

		(DE APPLY (FN ARGS)
		   (COND ((ATOM FN)
			  (COND ((GET FN (QUOTE EXPR))
				 (APPLY (GET FN (QUOTE EXPR)) ARGS))
				(T (APPLY (EVAL FN) ARGS))))
			 ((EQ (CAR FN) (QUOTE LAMBDA))
			  (PROG (Z)
				(BIND (CADR FN) ARGS)
				(SETQ Z (EVAL (CADDR FN)))
				(UNBIND (CADR FN))
				(RETURN Z)))
			 (T (APPLY (EVAL FN) ARGS))))

	The functions BIND and UNBIND implement variable bindings  as
described in the next section.

* 7.1 Variable Bindings

	This section attempts  to  explain  the  different  types  of
variable bindings and the difference between interpreter and compiler
bindings.

* 7.1.1  Bound and Free Occurrences

	An  occurrence  of  a  variable is a "bound occurrence" if the
variable  is  a  variable  in  any  LAMBDA  or  PROG  containing  the
occurrence so long as the occurrence is not contained in a FUNCTIONAL
argument which is contained in the  defining  LAMBDA  or  PROG.   The
defining  LAMBDA  or  PROG  is  the  innermost  LAMBDA  or PROG which
contains the variable in its parameter list.

Examples:

	(LAMBDA (X) (TIMES X Y))
		X has a bound occurrence.
		Y has a free occurrence.
	(LAMBDA (Y Z) (MAPCAR (FUNCTION (LAMBDA(X) (CONS X Y)))Z)
		X and Z have only bound occurrences.
		Y is bound by the outer LAMBDA and free in the inner.
SAILON 28.7                    CHAPTER 7                          7-3

* 7.1.2 Scope of Bindings

	A variable bound in a LAMBDA or PROG is  defined  during  the
dynamic  execution  of  the  LAMBDA  or  PROG.   Free  occurrences of
variables are defined if and only if either the variable is  globally
defined  or  the  variable  is  bound  in  any  LAMBDA  or PROG which
dynamically contains the free  occurrence.  A  variable  is  globally
defined  if  and  only  if  it  has a value at the top level of LISP.
Variables can be globally defined by SETQ at the top level.

* 7.1.3 Special Variables

	In  compiled  functions,  any  variable  which  is bound in a
LAMBDA or PROG and has a free occurrence elsewhere must  be  declared
SPECIAL (APPENDIX E).

Example:

	(LAMBDA (A B)
		(MAPCAR (FUNCTION (LAMBDA (X) (CONS A X))) B))

	The variable A which has a free occurrence must  be  declared
SPECIAL if the outer LAMBDA expression is to be compiled.

* 7.1.4 Binding Mechanisms

	All variables in interpreted functions, and SPECIAL variables
in compiled functions store their values in SPECIAL (or VALUE) cells.
These variables are bound at the entry to a LAMBDA or PROG by  saving
their  previous values on the SPECIAL pushdown list and storing their
new values in the SPECIAL cells.  All references to  these  variables
are  directly  to  their  SPECIAL  cells.  When the LAMBDA or PROG is
exited, the old values are restored from the SPECIAL pushdown list.

	In compiled functions, all variables not declared SPECIAL are
stored  on  the REGULAR pushdown list, and the SPECIAL cells (if they
exist) are not referenced.

# 7.2 The A-LIST and FUNARG Features

	The A-LIST which is used in some LISP  systems  to  implement
recursive  variable bindings does not exist here, but its effects are
simulated through a special A-LIST feature.  The functions  EVAL  and
APPLY  allow  an  extra  last argument to be passed which is either a
list of paired identifiers and values (like an A-LIST) or a  "binding
context pointer".

	In the case of an A-LIST second argument, EVAL and APPLY will
bind the special cells of  the  variables  in  the  A-LIST  to  their
specified  values,  saving  their  previous  bindings  on the special
pushdown list.  When EVAL and APPLY return, the variable bindings are
restored to their previous values.
SAILON 28.7                    CHAPTER 7                          7-4

	A  "binding  context  pointer"  (BCP)  is  a pointer into the
SPECIAL PUSHDOWN LIST  designating  a  level  in  recursive  variable
binding.  When EVAL and APPLY receive a BCP as their second argument,
all SPECIAL (VALUE) CELLS are restored to the values they had at  the
time  the  BCP  was  generated.    This then causes EVAL and APPLY to
reference these variables in the binding context which existed at the
time  of BCP generation.  This feature primarily is useful to prevent
variable name  conflicts  when  using  EVAL,  APPLY,  and  functional
arguments.   As  with  the  A-LIST,  when  EVAL  and  APPLY exit, the
previous bindings are restored.

	There are two ways to generate a BCP:

	If  an  FEXPR  is defined with two arguments, then the second
argument will be bound to the SPECIAL PUSHDOWN LIST level at the time
the FEXPR is called.

	The second way to generate a BCP is with *FUNCTION.

	(*FUNCTION "FN")

		*FUNCTION returns a list of the following form:

			(FUNARG FN * <BCP>)

where BCP is the SPECIAL PUSHDOWN LIST level at the time *FUNCTION is
called.   Whenever  such  a  functional  form  is  used in functional
context, all SPECIAL bindings are restored to the values they had  at
the  time  *FUNCTION was evaluated.  When the functional argument has
been APPLYed, the previous bindings are restored as with the A-LIST.

	The use of FUNARGS is discussed further by Robert Saunders[3].

Example using the BCP feature:

	(DF EXCHANGE (L SPECPDL)
	    (PROG(Z) (SETQ Z(EVAL (CAR L) SPECPDL))
		     (APPLY (FUNCTION SET)
			    (LIST (CAR L) (EVAL (CADR L) SPECPDL)
			     SPECPDL)
		     (APPLY (FUNCTION SET)
			    (LIST (CADR L) Z
			     SPECPDL)))

In  this  example, the use of the extra argument SPECPDL has only one
effect:  to avoid conflicts between internal and  external  variables
with names L and SPECPDL.

	(EXCHANGE  L  M)  will  cause  the  values  of  L and M to be
exchanged. The variable L in EXCHANGE is not referenced by the  calls
on SET.
SAILON 28.7                    CHAPTER 8                          8-1

                              CHAPTER 8

                       CONDITIONAL EXPRESSIONS


	A conditional expression has the following form:

!	(COND (e↓1,1 e↓1,2 ... e↓1,n↓1)

	      (e↓2,1  e↓2,2 ... e↓2,n↓2)
	       ...
	      (e↓m,1  e↓m,2 ... e↓m,n↓m))

where the e↓i,j's are any S-expressions.

	The e↓i,1's are considered to be predicates,  i.e.,  evaluate
to  a  truth  value.  The e↓i,1's are evaluated starting with e↓1,1 ,
e↓2,1 , etc., until the first e↓k,1 is found whose value is not  NIL.
Then   the   corresponding   e↓k,2  e↓k,3  ...e↓k,n↓k  are  evaluated
respectively and the value of e↓k,n↓k is returned  as  the  value  of
COND.  It is permissible for n↓k =1, in which case the value of e↓k,1
is the value of COND.  If all e↓i,1 evaluate to NIL, then NIL is  the
value of COND.

Examples:

	(DE NOT (X) (COND (X NIL) (T)))
	(DE AND (X Y) (COND (X (COND (Y T)))))
	(DE OR (X Y) (COND (X T) (Y T)))
	(DE IMPLIES (X Y) (COND (X (COND (Y T))) (T)))
SAILON 28.7                    CHAPTER 9                          9-1

                              CHAPTER 9

                             PREDICATES

	Predicates  test  S-expressions for particular values, forms,
or ranges of values.  All predicates described in this chapter return
either  NIL  or  T  corresponding to the truth values false and true,
unless otherwise noted.  Some  predicates  cause  error  messages  or
undefined  results  when  applied to S-expressions of the wrong type,
such as (MINUSP (QUOTE FOO)).

! (ATOM X)

	The  value  of  ATOM  is  T if X is either an identifier or a
number; NIL otherwise.

Examples:	(ATOM T)	= T
		(ATOM 1.23)	= T
		(ATOM (QUOTE (X Y Z)))	= NIL
		(ATOM (CDR (QUOTE (X)))	= T

! (EQ X Y)

	The  value  of EQ is T if X and Y are the same pointer, i.e.,
the same internal address.  Identifiers on  the  OBLIST  have  unique
addresses  and  therefore  EQ  will  be  T  if  X  and Y are the same
identifier.  EQ will also return T for equivalent INUMs,  since  they
are represented as addresses. However, EQ will not compare equivalent
numbers of any other kind. For non-atomic S-expressions, EQ is T if X
and Y are the same pointer.

Examples:	(EQ T T)	= T
		(EQ T NIL)	= NIL
		(EQ (QUOTE A)	(QUOTE B))	= NIL
		(EQ 1 1.0)	= NIL
		(EQ 1 1)	= T
		(EQ 1.0 1.0)	= NIL

(EQUAL X Y)

	The  value  of  EQUAL  is  T  if  X  and  Y   are   identical
S-expressions.  EQUAL  can also test for equality of numbers of mixed
types.  EQUAL is equivalent to:

	(LAMBDA(X Y) (COND ((EQ X Y) T)
			   ((AND (NUMBERP X) (NUMBERP Y))
			    (ZEROP (*DIF X Y)))
			   ((OR (ATOM X)(ATOM Y)) NIL)
			   ((EQUAL (CAR X) (CAR Y))
			    (EQUAL (CDR X) (CDR Y)))))
SAILON 28.7                    CHAPTER 9                          9-2

Examples:	(EQUAL T T)	= T
		(EQUAL 1 1)	= T
		(EQUAL 1 1.0)	= T
		(EQUAL (QUOTE (A B)) (QUOTE (A B)))	= T
		(EQUAL (QUOTE (T)) T)		= NIL

! 9.1 S-Expression Predicates

(NULL L)	= T if and only if L is NIL.

(MEMBER L1 L2)	= T if and only if L1 is EQUAL to a top level element of L2.

MEMBER is equivalent to:

	(LAMBDA(L1 l2) (COND ((ATOM L2) NIL)
			     ((EQUAL L1 (CAR L2))T)
			     (T(MEMBER L1 (CDR L2)))))

Examples:	(MEMBER (QUOTE (C D)) (QUOTE ((A B)(C D)E)))	= T
		(MEMBER (QUOTE C)(QUOTE (C))))	= NIL

(MEMQ L1 L2)	= T iff L1 is EQ to a top level element of L2.

MEMQ is equivalent to:

	(LAMBDA(L1 L2)(COND ((ATOM L2) NIL)
			    ((EQ L1 (CAR L2)) T)
			    (T(MEMQ L1 (CDR L2)))))

Examples:	(MEMQ (QUOTE (C D))(QUOTE ((A B)(C D) E))) = NIL
		(MEMQ (QUOTE A) (QUOTE (Q A B))) = T

!  9.2  Numerical Predicates

(NUMBERP X)	= T if X is a number of any type
		= Nil otherwise

(ZEROP X)	= T if X is zero of any numerical type
		= error if X is a non-numerical quantity
		= NIL otherwise

(MINUSP X)	= T if X is a negative number of any type
		= error if X is a non-numerical quantity
		= NIL otherwise

(*GREAT X Y)	= T if X and Y are numbers of any type and X > Y.
		= error if either X or Y is not a number
		= NIL otherwise

(*LESS X Y)	= (*GREAT Y X)
SAILON 28.7                    CHAPTER 9                          9-3

(GREATERP X↓1 X↓2 ...X↓n)	= T if (*GREAT X↓1 X↓2) and
				       (*GREAT X↓2 X↓3) and
				       (*GREAT X↓n-1 X↓n)

				= error if any X↓i is a non-numerical 
				  quality
				= NIL otherwise

(LESSP X↓1 X↓2 ... X↓n)		= (GREATERP X↓n X↓n-1 ... X↓1)

	Other numerical predicates may be defined as follows:

	(DE FLOATP (X) (COND ((EQ X (PLUS X 0))NIL)
			     ((EQ (CADR X) (QUOTE FLONUM)) T)
			     (T NIL)))
	(DE FIXP (X) (NOT(FLOATP X)))
	(DE ONEP (X) (ZEROP (DIFFERENCE X 1)))
	(DE EVENP (X) (ZEROP (REMAINDER X 2)))

! 9.3 Boolean Predicates

	The  Boolean  predicates  perform  logical  operations on the
truth values NIL and T.  A non-NIL value is considered equal to T.

(NOT X) = T if X is NIL
	= NIL otherwise

(AND X↓1 X↓2 ...X↓n)	= T if all X↓i are non-NIL
			= NIL otherwise

Note:	(AND) = T.   AND evaluates its arguments  from  left to right
	until	either NIL is  found  in  which  case  the  remaining
	arguments  are  not  evaluated,  or until the  last  argument
	is evaluated.

(OR X↓1 X↓2 ... X↓n)	= T if any X↓i is non-NIL
			= NIL otherwise

Note:	(OR) = NIL.  OR evaluates its arguments from left to right
	until either non-NIL  is found in which case the remaining
	arguments are not evaluated, or until the last argument is
	evaluated.
SAILON 28.7                    CHAPTER 10                        10-1

                             CHAPTER 10

                     FUNCTIONS ON S-EXPRESSIONS

	This  chapter  describes functions for building, fragmenting,
modifying, transforming, mapping,  and  searching  S-expressions,  as
well as some non-standard functions on S-expressions.

! 10.1 S-Expression Building Functions

(CONS X Y)

	The value of CONS of two S-expressions is the dotted pair  of
those S-expressions.

Example:	(CONS	(QUOTE A) (QUOTE B)) = (A.B)

Note:  See  Appendix D  for  information on functions associated with 
       CONSing, such as SPEAK, GCGAG, and GC.

(XCONS X Y) = (CONS Y X)

(NCONS X)   = (CONS X NIL)

(LIST X↓1 ... X↓n) = (CONS X↓1 (CONS X↓2 ...(CONS X↓n NIL)...))

	List evaluates all of its arguments and  returns  a  list  of
their values.

Examples:	(LIST) = NIL
		(LIST (QUOTE A)) = A
		(LIST (QUOTE A) (QUOTE B)) = (A B)

(*APPEND X Y)

	(DE *APPEND (X Y)
	     (COND ((NULL X) Y)
		   (T (CONS (CAR X) (*APPEND (CDR X) Y)))))

(APPEND X↓1 X↓2 ...X↓n) = (*APPEND X↓1 (*APPEND X↓2 ...(*APPEND X↓n NIL)...))

Example:	(APPEND) = NIL
		(APPEND (QUOTE (A B)) (QUOTE (C D)) (QUOTE (E))) = (A B C D E)

! 10.2 S-Expression Fragmenting Functions

(CAR L)

	The CAR of a non-atomic S-expression is the first element  of
that dotted pair.  CAR of an atom is undefined and will usually cause
an illegal memory reference.
SAILON 28.7                    CHAPTER 10                        10-2

(CDR L)

	The CDR of a non-atomic S-expression is the second (and last)
element of that dotted  pair.   The  CDR  of  an  identifier  is  its
property  list.   The  CDR  of  an  INUM  causes  an  illegal  memory
reference.  The CDR  of  any  other  number  is  the  list  structure
representation of that number.

Examples:	(CAR (QUOTE (A B C))) = A
		(CAR (QUOTE A)) is illegal
		(CDR (QUOTE (A B C))) = (B C)
		(CDR (QUOTE A)) is the property list of A
		(CDR (QUOTE (A)))  = NIL

CAAR, CADR,..., CDDDDR

	All  of  the  composite CAR-CDR functions with up to four A's
and D's are available.

Examples:	(CADR X) = (CAR (CDR X))
		(CAADDR X) = (CAR (CAR (CDR (CDR X))))

(LAST L)

	LAST  returns  the  last  part  of  a  list  according to the
following definition:

	(DE LAST (L)
	    (COND ((ATOM (CDR L)) L)
		  (T (LAST (CDR L)))))

Examples:	(LAST (QUOTE (A B C))) = (C) = (C.NIL)
		(LAST (QUOTE (A B . C))) = (B.C)

* 10.3 S-Expression Modifying Functions

	The following functions for manipulating S-expressions differ
from all others in that they actually modify existing list  structure
rather  than constructing new list structure.  These functions should
be used with caution since it is easy to create structures which will
confuse or destroy the interpreter.

(RPLACA X Y)

	Replaces the CAR of X by Y.  The value of RPLACA is the modified
S-expression X.

Example:	(RPLACA (QUOTE (A B C)) (QUOTE (C D))) = ((C D) B C)
SAILON 28.7                    CHAPTER 10                        10-3

Representation:
		     _________    _________   _________
		X  → | A |   | →  | B |   | → | C |NIL|
   BEFORE	     |___|___|    |___|___|   |___|___|

		     _________    _________
		Y  → | C |   | →  | D |NIL|          
		     |___|___|    |___|___|           

		     _________   _________   _________
		X  → | A |   | → | B |   | → | C |NIL|
		     |___|___|   |___|___|   |___|___|
 
		       ↓
		     _________    _________
		Y  → | C |   | →  | D |NIL|          
		     |___|___|    |___|___|           

(RPLACD X Y)

	RPLACD replaces the CDR of X by Y.  The value  of  RPLACD  is
the modified S-expression X.

(NCONC X↓1 X↓2 ... X↓n)

	NCONC is similar in effect to APPEND, but NCONC does not copy
list  structures.   NCONC  modifies  list structures by replacing the
last element of X↓1 by a pointer to X↓2, the last element of X↓2 by a
pointer  to  X↓3,  etc.  The value of NCONC is the modified list X↓1,
which is the concatenation of X↓1. X↓2, ..., X↓n.

Examples:	(NCONC) = NIL
		(NCONC (QUOTE (A B)) (QUOTE (C D))) = (A B C D)

Representation:
		      _________   _________
		X↓1 → | A |   | → | B |NIL|
   BEFORE	      |___|___|   |___|___|           

		      _________   _________           
		X↓2 → | C |   | → | D |NIL|
		      |___|___|   |___|___|

		      _________   _________
		X↓1 → | A |   | → | B |   |           
   AFTER	      |___|___|   |___|___|           
		     		        |
		        |---------------|
		      __↓______   _________           
		X↓2 → | C |   | → | D |NIL|
		      |___|___|   |___|___|
SAILON 28.7                    CHAPTER 10                        10-4

10.4 S-Expression Transforming Functions

	The following functions transform S-expressions from one form to
another.

(LENGTH L)

	LENGTH  returns  the number of top-level elements of the list
L. LENGTH is equivalent to:

	(DE LENGTH (L)
	    (COND ((ATOM L) 0)
		  (T (ADD1 (LENGTH (CDR L))))))

(REVERSE L)

	REVERSE  returns  the  reverse  of  the  top level of list L.
REVERSE is equivalent to:

	(DE REVERSE (L) (REVERSE1 L NIL))
	(DE REVERSE 1 (L M)
		(COND ((ATOM L) M)
		      (T (REVERSE1 (CDR L) (CONS (CAR L) M)))))

(SUBST X Y S)

	SUBST substitutes S-expression X for all EQUAL occurrences of
S-expression Y in S-expression S.  SUBST is equivalent to:

	(DE SUBST (X Y S)
            (COND ((EQUAL Y S) X)
		  ((ATOM S) S)
		  (T (CONS (SUBST X Y (CAR S))
			   (SUBST X Y (CDR S))))))

Note:  (SUBST 0 0 X) is useful for creating a copy of the list X.

Example:	(SUBST 5 (QUOTE FIVE) (QUOTE (FIVE PLUS FIVE IS TEN)))
		       = (5 PLUS 5 IS TEN)

10.5 S-Expression Mapping Functions

	The  following  functions perform mappings of lists according
to the functional arguments supplied.

(MAP FN L)

	MAP  applies the function FN of one argument to list L and to
successive CDRs of L until L is reduced to NIL.  The value of MAP  is
NIL. MAP is equivalent to:
SAILON 28.7                    CHAPTER 10                        10-5

	(DE MAP (FN L)
	    (PROG NIL
	     L1	  (COND ((NULL L)(RETURN NIL)))
		  (FN L)
		  (SETQ L (CDR L))
		  (GO L1)))

Example:	(MAP (FUNCTION PRINT) (QUOTE (X Y Z))) =

	PRINT:		(X Y Z)
	PRINT:		(Y Z)
	PRINT:		(Z)
	PRINT:		NIL

(MAPC FN L)

	MAPC is identical to MAP except that MAPC applies function FN
to the CAR of the remaining list at each step.  MAPC is equivalent to:

	(DE MAPC (FN L)
	    (PROG NIL
	    L1    (COND ((NULL L)(RETURN NIL)))
			(FN (CAR L))
			(SETQ L (CDR L))
			(GO L1)))

Example:	(MAPC (FUNCTION PRINT) (QUOTE (X Y Z))) =

	PRINT:		X
	PRINT:		Y
	PRINT:		Z
	PRINT:		NIL

(MAPLIST FN L)

	MAPLIST applies the function FN of one argument to list L and
to  successive  CDRs  of  L  until L is reduced to NIL.  The value of
MAPLIST is the list of values returned by FN.  MAPLIST is  equivalent
to:

	(DE MAPLIST (FN L)
	    (COND ((NULL L) NIL)
	    (T (CONS (FN L) (MAPLIST FN (CDR L))))))


Examples:	(MAPLIST (FUNCTION CAR) (QUOTE (A B C D))) = (A B C D)
		(MAPLIST (FUNCTION REVERSE) (QUOTE (A B C D))) =
			((D C B A) (D C B) (D C) (D))

(MAPCAR FN L)
SAILON 28.7                    CHAPTER 10                        10-6

	MAPCAR is identical to MAPLIST except that MAPCAR applies  FN
to  the CAR of the remaining list at each step.  MAPCAR is equivalent
to:

	(DE MAPCAR (FN L)
	    (COND ((NULL L) NIL)
		  (T (CONS (FN (CAR L)) (MAPCAR FN (CDR L))))))

Examples:	(MAPCAR (FUNCTION NCONS) (QUOTE (A B C D))) = ((A) (B) (C) (D))
		(MAPCAR (FUNCTION ATOM) (QUOTE ((X) Y (Z)))) = (NIL T NIL)

10.6  S-Expression Searching Functions

(ASSOC X L)	
	
	ASSOC  searches  the  list of dotted pairs L for a pair whose
CAR is EQ to X.  If such a pair is found it is returned as the  value
of ASSOC, otherwise NIL is returned.  ASSOC is equivalent to:

	(DE ASSOC (X L)	
	    (COND ((NULL L) NIL)
		  ((EQ X (CAAR L)) (CAR L))
		  (T (ASSOC X (CDR L)))))

Example:	(ASSOC 1 (QUOTE ((1.ONE) (2.TWO)))) = (1.ONE)

(SASSOC X L FN)

	SASSOC searches the list of dotted pairs L for a  pair  whose
CAR  is EQ to X.  If such a pair is found it is returned as the value
of ASSOC, otherwise the value of FN, a function of no  arguments,  is
returned.

	(DE SASSOC (X L FN)

	    (COND ((NULL L) (FN))
		  ((EQ X (CAAR L)) (CAR L))
		  (T (SASSOC X (CDR L) FN))))

Example:	(SASSOC 0 (QUOTE ((1.ONE) (2.TWO)))
			  (FUNCTION (LAMBDA NIL (QUOTE LOSE)))) = LOSE

10.7  Character List Transforming Functions

(EXPLODE L)

	EXPLODE transforms an S-expression  into  a  list  of  single
character  identifiers  identical to the sequence of characters which
would be produced by PRINC.

Example:	(EXPLODEC (QUOTE (DX_/-_DY)))
		= (/(D X / _ / - / _ D Y/))
SAILON 28.7                    CHAPTER 10                        10-7

(FLATSIZE L)	= (LENGTH (EXPLODE L))

(MAKNUM L)

	MAKNUM  transforms  a  list  of  single character identifiers
(actually takes the first  character  of  each  identifier)  into  an
S-expression  identical  to  that  which would be produced by READing
those  characters.   MAKNAM  however  does  not  INTERN  any  of  the
identifiers in the S-expression it produces.

Examples:	(MAKNUM (QUOTE (A P P L E))) = APPLE
		(MAKNAM (QUOTE (//_/)))) = /)

(READLIST L)

	READLIST is identical to MAKNAM except that  READLIST  INTERNs
all  identifiers  in  the  S-expression it produces.  READLIST is the
logical inverse of EXPLODE, i.e.,

		(READLIST (EXPLODE L)) = L
		(EXPLODE (READLIST L)) = L
SAILON 28.7                    CHAPTER 11                        11-1

                             CHAPTER 11

                      FUNCTIONS ON IDENTIFIERS

	There are three basic  types  of  functions  on  identifiers:
those  which  manipulate their property lists, those which create new
identifiers, and those which control their membership in the OBLIST.

NOTE:  All functions  described  in  this  chapter  which  expect  an
identifier  as  one  (or  more)  of  its  arguments  will give either
erroneous results, or an error condition if  any  S-expression  other
than an identifier is supplied.

11.1 Property List Functions

(GET I P)

	GET  is  a  function  which searches the property list of the
identifier I looking for the property name which is EQ to P.  If such
a property name is found, the value associated with it is returned as
the value of GET, otherwise NIL is  returned.   Note  that  confusion
exists  if  the  property  is  found,  but  its value is NIL.  GET is
equivalent to:

	(DE GET (I P) (COND ((NULL (CDR I)) NIL)
			    ((EQ (CADR I) P) (CADDR I))
			    (T (GET (CDDR I) P))))

(GETL I L)

	GETL is another function which searches property lists.  GETL
searches the property list of the identifier I looking for the  first
property  which  is  a member (MEMQ) of the list L.  GETL returns the
remaining property list, including the  property  name  if  any  such
property was found, NIL otherwise. GETL is equivalent to:

	(DE GETL (I L) (COND ((NULL (CDR I)) NIL)
			     ((MEMQ (CADR I) L) (CDR I))
			     (T (GETL (CDDR I) L))))

(PUTPROP I V P)

	PUTPROP is a function which enters the property name  P  with
property  value  V  into  the  property list of identifier I.  If the
property name P is already in the property  list,  the  old  property
value  is  replaced by the new one; otherwise the new property name P
and its value V are placed on the beginning  of  the  property  list.
PUTPROP returns V.

(REMPROP I P)
SAILON 28.7                    CHAPTER 11                        11-2

	REMPROP  removes  the  property  P  from the property list of
identifier I. REMPROP returns T if there was  such  a  property,  NIL
otherwise.

	SET and SETQ are used to change the values of variables which
are  bound  by  either  LAMBDA  or PROG, or variables which are bound
globally. (See 7.1).

* (SET E V)

	SET changes the value of  the  identifier  specified  by  the
expression E to V and returns to V.  Both arguments are evaluated.

Note:   In compiled functions, SET can be used only on globally bound
and special variables.

! (SETQ "ID" V)

	SETQ changes the value of  ID  to  V  and  returns  V.   SETQ
evaluates V, but does not evaluate ID.

(DEFPROP  "I"  "V"  "P") = (PROG2 (PUTPROP (QUOTE I) (QUOTE V) (QUOTE
P))(QUOTE I))

	DEFPROP is the same  as  PUTPROP  except  that  it  does  not
evaluate its arguments, and DEFPROP returns I.

Example:	(DEFPROP POSP (LAMBDA (X) (GREATERP X 0)) EXPR)

(DE "ID" "ARGS" "BODY")

	DE places the form (LAMBDA ARGS BODY) on the property list of
ID under property EXPR.  If ID previously had any of  the  properties
EXPR,  FEXPR,  SUBR,  FSUBR, LSUBR, or MACRO, then DE will return the
list (ID REDEFINED). Otherwise, DE returns ID.

(DF "ID" "ARGS" "BODY")

	Same as DE except defines a function with FEXPR property.

(DM "ID" "ARGS" "BODY")

	Same as DE except defines a MACRO.

11.2 OBLIST Functions

(INTERN I)	
	INTERN  puts  the  identifier  I in the appropriate bucket of
OBLIST. If the identifier is aready a  member  of  the  OBLIST,  then
INTERN returns a pointer to the identifier already there.  Otherwise,
INTERN returns I.
SAILON 28.7                    CHAPTER 11                        11-3

Note:	INTERN is only necessary when an identifier which was created
by
	GENSYM, MAKNAM, or ASCII needs to be uniquely stored.

(REMOB "X↓1" "X↓2 ... "X↓n")
	REMOB removes all of the identifiers X↓1, X↓2, ... , X↓n from
the OBLIST and returns NIL.  None of the X↓i's are evaluated.

Example:  (REMOB FOO BAZ)

11.3 Identifier Creating Functions

	The following functions create new  identifiers  but  do  not
INTERN them onto the OBLIST.

(GENSYM)

	GENSYM  increments the generated symbol counter and returns a
new identifier specified by  the  counter.   The  GENSYM  counter  is
initialized  to  the  identifier  G0000.   Successive  executions  of
(GENSYM) will return.

	G0001, G0002, G0003, ...

(CSYM "I")

	CSYM initializes generated symbol counter to  the  identifier
I, and returns I.  CSYM does not evaluate its argument.

Example:	(CSYM ARY00)	= ARY00
		(GENSYM)	= ARY01
		(GENSYM)	= ARY02
		  etc.

(ASCII N)

	ASCII creates a single character identifier whose ASCII print
name equals N.

Example:  	(AsCII 101) is an identifier with print name "A".
SAILON 28.7                    CHAPTER 12                        12-1

                             CHAPTER 12

                        FUNCTIONS ON NUMBERS

	There are two types of functions which operate on numbers  to
create new numbers:  arithmetic and logical.

! 12.1 Arithmetic Functions

	Unless  otherwise  noted,  the following arithmetic functions
are  defined  for  both  integer,  real  and  mixed  combinations  of
arguments,  and  evaluate all their arguments.  The result is real if
any argument is real, and integer if all arguments are integer.  Most
arithmetic  functions  may  cause  overflow  which  produces an error
message.

(MINUS X)		= -X

(*PLUS X Y)		= X + Y

(PLUS X1 X2 ... Xn)	= X1 + X2 + ... + Xn

(*DIF X Y)		= X - Y

(DIFFERENCE X1 X2...Xn) = X1 - X2 - ... -Xn

(*TIMES X Y)		= X * Y

(TIMES X1 X2 ... Xn)	= X1 * X2 * ... * Xn

(*QUO X Y)		= X / Y

(QUOTIENT X1 X2 ...Xn)	= X1 / X2 / ... / Xn

	For integer arguments, *QUO and  QUOTIENT  give  the  integer
part of the real quotient of the arguments.

Examples:	(*QUO 5 2) = 2
		(*QUO -5 2) = -2

(REMAINDER X Y) ... X - (X / Y) * Y

Note:  Remainder is not defined for real arguments.

(DIVIDE X Y) = (CONS (QUOTIENT X Y) (REMAINDER X Y))

(GCD X Y) GCD returns the greatest common divisor of the  integers  X
and Y.

(ADD1 X)	= X + 1 (SUB1 X)	= X - 1
(ABS X)		= | X |
SAILON 28.7                    CHAPTER 12                        12-2

(FIX X) returns the largest integer not greater than X.

Examples:	(FIX 1) = 1
		(FIX 1.1) = 1
		(FIX -1.1) = -2		not -1

	Other arithmetic functions not defined in the LISP interpreter
can be defined as follows:

(FLOAT X) = (*PLUS X 0.0)

(RECIP X) = (QUOTIENT 1 X)

(SIGN X) = (COND ((ZEROP X) 0)
		((MINUSP x) -1)
		(T 1))

(ROUND X) = (TIMES (SIGN X) (FIX (PLUS (ABS X) 0.5)))

Examples:	(ROUND .5) = 1
		(ROUND .49) = 0
		(ROUND -.49) = 0
		(ROUND -35.1) = -35

(MIN X Y) = (COND ((LESSP X Y) X) (Y))

(MAX X Y) = (COND ((LESSP X Y) Y) (X))

Examples:	(MINUS 1)		= -1
		(MINUS -1.2)		= 1.2
		(PLUS 1 2 3.1		= 6.1
		(PLUS 6 3 -2)		= 7
		(DIFFERENCE 6 3 1)	= 2
		(TIMES -2 2.0)		= -4.0
		(QUOTIENT 5 2)		= 2
		(QUOTIENT 5.0 2)	= 2.5
		(QUOTIENT -5 2)	= 2
		(REMAINDER 5 2)		= 1
		(REMAINDER -5 2)	= -1
		(REMAINDER 5.0 2)	= undefined
		(ABS -32.5)		= 32.5
		(FIX 32.5)		= 32.
		(FIX -32.5)		= -33.

12.2 Logical Functions

	The following functions are intended to operate on  INUM  and
FIXNUM  arguments,  but  their  results are not defined for BIGNUM or
FLONUM (real) arguments.

(BOOLE N X1 X2 ... Xn)
SAILON 28.7                    CHAPTER 12                        12-3

	BOOLE causes a 36 bit Boolean operation to  be  performed  on
its  arguments.   The  value  of  N  specifies  which  of  16 Boolean
operations to perform.

	For n = 2, each bit↓i in ( BOOLE N A B) is defined:

	N	result		N	result

					_ _
	0	0		10	A↓i ∧ B↓i

	1	A↓i∧B↓i		11	A↓i ≡ B↓i

		_			_
	2	A↓i∧B↓i		12	A↓i

					_
	3	B↓i		13	A↓i∨B↓i

		_			_
	4	A↓i∧B↓i		14	B↓i

					_
	5	A↓i		15	A↓i∨B↓i

					_
	6	A↓i ≠ B↓i	16	A↓i∨B↓i

	7	A↓i∨B↓i		17	1

For n > 2, BOOLE is defined:

	(BOOLE N ... (BOOLE N (BOOLE N X1 X2) X3) ... Xn)

(LSH X N)

	LSH performs a logical left shift of N places on X.  If n  is
negative,  X  will be shifted right.  In both cases, vacated bits are
filled with zeros.

Examples with IBASE = 8

	(BOOLE 1 76 133)	= 32
	(BOOLE 1 76 133 70)	= 30
	(BOOLE 12 13 0)		= 777777777764
	(BOOLE 7 7 12)		= 17
	(LSH 15 2)		= 64
	(LSH 15 -2)		= 3
	(LSH -1 -2)		= 177777777777
SAILON 28.7                    CHAPTER 13                        13-1

                             CHAPTER 13

                              PROGRAMS


	The   "program   feature"  allows  one  to  write  ALGOL-like
sequences of statements with program variables and labels.

(PROG "VARLIST" "BODY")

	PROG is a function which takes as arguments VARLIST,  a  list
of  program  variables  which are initialized to NIL when the PROG is
entered (see 7.1), and a BODY which is a list of  labels  (which  are
identifiers) and statements which are non-atomic S-expressions.  PROG
evaluates its statements in sequence until either a RETURN or  GO  is
evaluated, or the list of statements is exhausted, in which the value
of PROG is NIL.

(RETURN X)

	RETURN causes the PROG containing it to be  exited  with  the
value X.

(GO "ID")

	GO  causes  the  sequence  of  control  within  a  PROG to be
transferred to  the  next  statement  following  the  label  ID.   In
interpreted  PROGs,  if  ID is non-atomic, it is repeatedly evaluated
until an atomic value is found.  However, in compiled  PROGs,  ID  is
evaluated only once.  GO cannot transfer into or out of a PROG.

Note:   Both  RETURN and GO should only occur either at the top level
of a PROG, or in compositions of COND, AND, OR, and NOT which are  at
the top level of a PROG.

Example:  The function LENGTH may be defined as follows:

		(DE LENGTH (L)
		(PROG (N)
			(SETQ N 0)
		L1 (COND ((ATOM L) (RETURN N)))
			(SETQ N (ADD1 N))
			(SETQ L (CDR L))
			(GO L1)))

(PROG2 X↓1 X↓2 ... X↓n) , n≤5.

	PROG2  evaluates all expressions X↓1 X↓2 ... X↓n, and returns
the value of X↓2.
SAILON 28.7                    CHAPTER 14                        14-1

                             CHAPTER 14

                            INPUT/OUTPUT

14.1 File Names

Syntax:	<filename - list>	::= <device-name>
				::= <filename-list><device-name>
				::= <filename-list><file - name>

	<device - name>		::= <identifier> :
				::= (<atom><atom>)

	<filename>		::= <identifier>
				::= (<identifier> . <identifier>)

Semantics:	
	A device-name is either an identifier ending with  colon  (:)
which  is  the  name  of  some  input  or  output  device,  or a list
containing a project-programmer number which implicitly specifies the
disk.

	A filename is either an identifier which specifies a filename
with a blank extension, or a dotted pair of filename  and  extension.
In both cases the filename applies to the most recently (to the left)
specified device-name.

14.2 Channel Names

	Channel names can optionally be assigned to files selected by
the  functions  INPUT  and  OUTPUT.  A channel name is any identifier
which is not followed by a colon.  If no channel name is specified to
INPUT or OUTPUT then the channel name T is assumed.  The channel name
NIL specifies the teletype in the functions INC and OUTC.  Up  to  14
channels may be active at any time.

14.3 Input

14.3.1 Selection and Control

(INPUT "CHANNEL" . "FILENAME-LIST")

	INPUT   releases  any  file  previously  initialized  on  the
channel, and initializes for input the first file  specified  by  the
filename-list.  INPUT  returns  the  channel  if one was specified, T
otherwise.  INPUT does not evaluate its arguments.

(INC CHANNEL ACTION)	
	INC selects the specified channel for input.  The channel NIL
selects  the  teletype.  If ACTION = NIL then the previously selected
input file is not released, but only deselected.  If ACTION = T  then
that  file  is  released,  making  the  previously  selected  channel
SAILON 28.7                    CHAPTER 14                        14-2

available. At the top level, ACTION need not be specified.

	The input functions in 14.3.3 receive input from the selected
input  channel.   When  a  file on the selected channel is exhausted,
then  the  next  file  in  the  filename-list  for  the  channel   is
initialized  and  input,  until the filename-list is exhausted.  Then
the teletype is automatically selected  for  input  and  (ERR  (QUOTE
$EOF$))  is  called.  The  use  of  ERRSET around any functions which
accept input therefore makes it possible to detect end of  file.   If
no  ERRSET  is  used,  control returns to the top level of LISP.  INC
evaluates its arguments, and returns the previously selected  channel
name.

	In  order  to  READ  from  multiple  input  sources, separate
channels should be initialized by INPUT, and INC can then  select  the
appropriate channel to READ from.

Example: The following show a fairly typical sort of manipulation of two
	files at once.

 (LAMBDA (FILE)
  (PROG (CHAN1 CHAN2 EXPR1 EXPR2)
	(SETQ CHAN1 (INPUT  DSK: FOO)))	;initialize FOO with channel name T
	(SETQ CHAN2 (EVAL (LIST @INPUT (GENSYM) @DSK: FILE)))
		;this file is given a GENSYM channel name to prevent
		with any existing channels
   LOOP (INC CHAN1 NIL)	;select first channel
	(SETQ EXPR1 (READ))	;read an expression from FOO
	(COND ((EQ EXPR1 (QUOTE *EOF*)) (GO EXIT1)))	;end of first file?
	(SETQ EXPR1 (CAR EXPR1))	;undo effect of ERRSET
	(INC CHAN2 NIL)	;open second channel
	(SETQ EXPR2 (ERRSET READ))	;read an expression
	(COND ((EQ EXPR2 (QUOTE *EOF*)) (GO EXIT2))	;end of this file?
	      ((ATOM EXPR2) (GO ERROR)))	;read error?
	(SETQ EXPR2 (CAR EXPR2))	;undo effect of errset
	      ..........................
	      process in EXPR1 and EXPR2
	      ..........................
	      (GO LOOP)
   ERROR	;error routine
   EXIT1	;exit when first file ends first
   EXIT2	;exit when sencond file ends first
	      etc.


(DSKIN . "FILENAME-LIST")

	In  loading  a  file  into a LISP program, it is not normally
necessary to make use of the full generality  available  in  INC  and
INPUT.  The  function DSKIN is supplied for this purpose.  It has the
same effect as doing INC and INPUT on its arguments, except  that  no
channel  name  is  admissible,  and  no device name is required.  The
SAILON 28.7                    CHAPTER 14                        14-3

channel name will always be T, and `DSK' will be supplied as a device
name, if none is given.

Example:

	(DSKIN FOO DTA3: BAR (1,JMC) (SIMU.MAN))

	will READ the files FOO from DSK:, BAR from DTA3:  and
	SIMU.MAN from the disk area [1,JMC].


	When reading an input file, it is sometimes desirable to know
the  page  and  line being read from.  PGLINE returns the dotted pair
(page number . line number) for the selected input  file.   The  page
number  is  applicable only to STOPGAP files. If the file has no line
numbers, PGLINE will always return (1 . 0).

14.3.2 Teletype Input Control

	When input is from the teletype, READ is terminated by either
an  entire  S-expression or by an incomplete S-expression followed by
altmode.  Altmode has the effect of typing a space  followed  by  the
appropriate  number  of  right  parens  to complete the S-expression.
This feature is particularly useful when an unknown number  of  right
parens are needed or when in (DDTIN NIL) mode.

* (DDTIN X)

	DDTIN  is a function which selects teletype input mode.  With
(DDTIN NIL), and typing to READ, READCH, or TYI, a rubout will delete
the  last  character typed, and control U (↑U) will delete the entire
last line typed.  Input is not seen by LISP until either  altmode  or
carriage return is typed.

	With  (DDTIN  T) and typing to READ, a rubout will delete the
entire S-expression being read and start reading again.

Note:	(DDTIN T) is not recommended when the time-sharing system is
	swapping, since the program is reactivated (and hence swapped
	into core) after every character typed.

14.3.3 Input Transfer

!  (READ)

	READ causes  the  next  S-expression  to  be  read  from  the
selected input device, and returns the internal representation of the
S-expression. READ uses INTERN to guarantee that  references  to  the
same identifier are EQ.

	READ  will  accept  any  S-expression  which  conforms to the
following syntax:
SAILON 28.7                    CHAPTER 14                        14-4

Syntax:

	<readable S-expr>	::= <atom>
				::= @<readable S-expr>
				::= (<readable S-exprlist>
					{.<readableS-expr>})
				::= [<unbalanced S-expression list>]
				::= ( )		= NIL

	<readable S-expr list>	::= <readable S-expr>
				::= <readable S-expr><readable S-
					expression list>

Semantics:

	The delimiter "@"  designates  that  the  following  readable
S-expression is to be quoted.

Examples:	@A	means (QUOTE A)
		@(@A B) means (QUOTE ((QUOTE A) B))
		@@A	means (QUOTE (QUOTE A)))

	The  delimiters "[" and "]" operate as "super-parentheses". A
right bracket "]" will close all open left parentheses ")" up to  the
matching  left bracket "[".  If there is no matching left bracket, it
will close the entire S-expression as does  altmode.   No  syntax  is
given for unbalanced-S-expression-list, but it is intended to mean an
S-expression-list which is lacking one or more right parentheses.

Example:	(COND [(ATOM X) (REVERSE(CDR Y][T(APPEND Y Z])
		(COND ((ATOM X) (REVERSE(CDR Y)))(T(APPEND Y Z)))

(READCH)

	READCH causes the next character to be read from the selected
input  device  and  returns  the   corresponding   single   character
identifier. READCH also uses INTERN.

(TYI)

	TYI  causes  the  next character to be read from the selected
input device and returns the ASCII code for that character.

	A function  TEREAD  which  ignores  all  characters  until  a
line-feed is seen can be defined:

	(DE TEREAD NIL
	(PROG NIL
	L	(COND ((EQ (TYI) 12) (RETURN NIL)))
		(GO L)))
SAILON 28.7                    CHAPTER 14                        14-5

14.4 Output

14.4.1 Selection and Control

(OUTPUT "CHANNEL" . "FILENAME-LIST")

	OUTPUT initializes for output on the  specified  channel  the
single file specified by the filename-list.  OUTPUT does not evaluate
its  arguments,  and  returns  the  channel  name  if  specified,   T
otherwise.

(OUTC CHANNEL ACTION)
	OUTC selects the specified channel for output.   The  channel
NIL  selects  the  teletype.  The output functions in 14.4.3 transfer
output to the selected output channel.

	If ACTION = NIL, then the previously selected output file  is
not  closed,  but  only  deselected.  If ACTION = T then that file is
closed, i.e.,  an  end  of  file  is  written.   OUTC  evaluates  its
arguments  and  returns  the previously selected channel name. At the
top level, ACTION need not be specified.

Examples:  (At the top level)

	(OUTC (OUTPUT LPT:) T)
	(OUTC NIL T)
	(OUTPUT FOO DSK:  BAZ)
	(OUTC (QUOTE FOO) NIL)

(LINELENGTH N)

	LINELENGTH  is  used  to examine or change the maximum output
linelength on the selected output channel.   If  N  =  NIL  then  the
current linelength is returned unchanged, otherwise the linelength is
changed to the value of N which is returned and must be an integer.

(CHRCT)

	CHRCT returns the number of character positions remaining  on
the output line of the selected output channel.

	When  characters  are  output,  if CHRCT is made negative, an
ASCII 176 followed by a carriage-return and a  line-feed  are  output.
These characters are completely ignored on input.  (See Chapter 3).

14.4.2 Output Transfer

! (PRIN1 S)

	PRIN1 causes the S-expression S to be printed on the selected
output  device  with  no  preceding  or  following spaces. PRIN1 also
inserts slashes ("/") before  any  characters  in  identifiers  which
SAILON 28.7                    CHAPTER 14                        14-6

would  be  syntactically incorrect otherwise (see Chapter 3).  Double
quotes around strings are printed.

(PRINC S)

	PRINC is the  same  as  PRIN1  except  that  no  slashes  are
inserted and double quotes around strings are not printed.

(TERPRI X)

	TERPRI prints a carriage-return and line-feed and returns the
value of X. X may be omitted if the value of TERPRI is not used.

Example:	(PRINC(TERPRI X))

is the same as	
		(PROG2 (TERPRI)(PRINC X))

! (PRINT S)

	= (PROG2 (TERPRI)
		(PRIN1 S)
		(PRINC (QUOTE/_)))

(TYO N)

	TYO  prints the character whose ASCII value is N, and returns
N.
SAILON 28.7                    CHAPTER 15                        15-1

                             CHAPTER 15

                               ARRAYS

(ARRAY "ID" TYPE B↓1 B↓2 ... B↓n)	n≤ 5.

	ARRAY is a function which declares an array with name ID, and
places an array referencing function on the property list of ID. TYPE
determines the type of an array as follows:

	TYPE	INITIAL VALUE	ARRAY ELEMENT

		T	NIL	LISP S-expressions stored as 
				pointers; 2 per word.

	NIL	0.0		REAL numbers stored one per word in
				PDP-6/10 floating point representation.

	36.	0		36 bit 2/s complement integers stored
				1 per word.

	0<n<36.	0		n  bit   positive   integers   packed
				[36./n] per word.

B↓1 B↓2 ... B↓n are array subscript bounds which should  evaluate  to
either  positive  integers S↓i, or to dotted pairs of integers (L↓i .
U↓i) where L↓i≤U↓i, which specify lower and upper subscript bounds as
follows:

	B↓i	LOWER BOUND	UPPER BOUND	LENGTH

	S↓i	0		S↓i - 1		S↓i

(L↓i . U↓i) L↓i		U↓i		U↓i-L↓i + 1

The elements of an array are referenced by:	
		(<array name> i↓1 i↓2 ... i↓n) where L↓j ≤ i↓j < U↓j.

The ARRAY subscripts i↓j must  be  integers.   References  to  memory
locations  outside  of the area reserved for the array are prohibited
and will cause an illegal memory reference message.   Array  elements
are stored in BINARY PROGRAM SPACE.

Examples:

1)  To  declare  a  1 dimensional array CHARS of 7 bit characters and
with subscripts 1 to 50:

		(ARRAY CHARS 7 (QUOTE (1 . 50)))

	The first element of CHARS is referenced:
SAILON 28.7                    CHAPTER 15                        15-2

		(CHARS 1)

2) To declare a 2-dimensional  array  A  of  REAL  numbers  and  with
subscripts 0 ≤ i < N, 0 ≤ j < M:

		(ARRAY A NIL N M)

3)  To  declare  a  1-dimensional array FOO of S-expressions and with
subscripts -K ≤ i ≤ K:

		(ARRAY FOO T (CONS (MINUS K) K))

*(EXARRAY "ID" TYPE B↓1 B↓2 ... B↓n) N ≤ 5.

	EXARRAY is identical to ARRAY except that array elements  are
stored in the body of a subroutine loaded by the LOADER (see Appendix
H), and exarray elements are not initialized.  The array  referencing
subroutine  is stored in BINARY PROGRAM SPACE as with ARRAY.  EXARRAY
searches symbol tables as does GETSYM (see Appendix H).

Note:	Both ARRAY and EXARRAY  consume  BINARY  PROGRAM  SPACE.   If
there is insufficient room there (see Appendix C) the  error  message
"BINARY PROGRAM SPACE EXCEEDED" will result.

(STORE ("ID" i↓1 i↓2 ... i↓n) value)

	STORE changes the value of the  specified  array  element  to
value, and returns value.

Note:	STORE evaluates its second argument first.

Examples:  With the arrays declared previously:

		(STORE (FOO 0) (QUOTE (A B)))
		(STORE (FOO (BAZ L)) 1)
		(STORE (A I J) (A J I))
		(STORE (CHARS 1) 17)

15.1 Examine and Deposit

(EXAMINE N)

	EXAMINE returns as an integer the contents of memory location
N.

(DEPOSIT N V)

	DEPOSIT stores the integer V in memory location N and returns
V.
SAILON 28.7                    CHAPTER 16                        16-1

                             CHAPTER 16

                           OTHER FUNCTIONS

(TIME)

	TIME returns the number of milliseconds your job has computed
since you logged into the system.

(ERRSET E "F")

	ERRSET evaluates the S-expression E and if  no  error  occurs
during  its evaluation, ERRSET returns (LIST E).  If an error occurs,
then the error message will be suppressed if and only if F ≠ NIL, and
NIL  is  returned  as  the  value  of ERRSET.  If the function ERR is
called during evaluation, then  no  message  is  printed  and  ERRSET
returns the value returned by ERR.

	The  following example shows the use of ERRSET to keep trying
to initialize the line printer until it is available:

	(DE LPTGRAB NIL
	(PROG NIL
	L (COND ((ATOM(ERRSET (OUTPUT LPT:) T))
		(WAIT) (GO L)))))

where  WAIT  is  some  function  (such as the time-sharing sleep UUO)
which causes a delay.

(ERR E)

	ERR returns the value of E to the most recent ERRSET,  or  to
the top level of LISP if there is no ERRSET.

(*RSET X) flag = NIL initially

*RSET  sets  a special flag in the interpreter to the value of X, and
returns the previous value of the flag. Normally, with  (*RSET  NIL),
when  an  error  occurs,  special variables are restored to their top
level values from the  special  pushdown  list,  and  the  top  level
READ-EVAL-PRINT loop is entered.

	With  (*RSET  T), specials are not restored, neither pushdown
list is changed, and the READ-EVAL-PRINT loop is entered.  This makes
it  possible  to  examine  the variable bindings immediately after an
error message has been printed.  To restore special bindings to their
top  level  values  and  return to the top level, type a bell (π), or
evaluate (ERR).

(BAKGAG X)
SAILON 28.7                    CHAPTER 16                        16-2

	BAKGAG sets a special flag in the interpreter to the value of
X and returns the previous setting of the flag.  Only if the  flag  ≠
NIL  when an error occurs, then a backtrace is printed as a series of
function calls, determined from the regular pushdown  list,  starting
from  the  most  recent  function  call.   If X is an integer, then X
specifies the number of regular pushdown list words  to  include  the
backtrace.   If  X  is  T,  then  the entire regular pushdown list is
backtraced to the most recent ERRSET.  The format for printing is:

	printout		meaning

	fn1-fn2			Function 1 called function 2

	fn1 - EVALARGS		The  arguments  to  fn1   are   being
evaluated
				before entering function 1.

	fn1 - ENTER		The function 1 is entered.

	? - fn1			Some internal LISP function called
				function 1.

Note:	The BACKTRACE printout is often confused by compiled function
	calls of the form (RETURN (FOO X)) which is compiled as
	(JCALL  (E  FOO))  which  can be changed to (JRST entrance to
FOO),
	which will not show up in the BACKTRACE.

(INITFN FN)

	INITFN  selects  the  function  of  no  arguments  FN  as  an
initialization function which is evaluated after a LISP error  return
to  the  top  level  has occurred or whenever a BELL is typed. INITFN
returns the previously selected initialization function.

	Initialization functions are useful when it is  desirable  to
change the top level of LISP.  For instance,

	(INITFN (FUNCTION EVALQUOTE))

causes the top level to become EVALQUOTE instead of EVAL.
SAILON 28.7                    APPENDIX A                         A-1

                             APPENDIX A

                               ALVINE

                            by John Allen


	ALVINE  is  a  LISP  editor  which  is  very  convenient  for
interactive  debugging.   ALVINE  allows  one  to  edit both function
definitions and S-expression values.  ALVINE is characterized by  the
simplicity with which one can correct a parenthesis mismatch and make
context searches and replacements.  This simplicity arises  from  the
data  structure  ALVINE  uses  to  represent  an  S-expression.   All
S-expressions are flattened into a list of atoms including the  atoms
%LP,  %RP  and  %D which represent "(", ")" and ".".  Because of this
representation, ALVINE looks more like a string type text editor with
the  smallest  unit of resolution being a single atom or S-expression
delimiter (%LP %RP or %D).

	ALVINE has a pointer which can move through the string  being
edited.  The editing functions affect only the string to the right of
the pointer.

	ALVINE also contains functions for manipulating  input-output
files, and GRINDEF which is useful for printing function definitions.

	ALVINE  is not ordinarily a resident part of the LISP system,
but is automatically loaded whenever the function ED is called.

(ED X)

	ED loads ALVINE if it is not already loaded.  If X = NIL then
the editor is entered.  If X = T, the editor is not entered.  This is
useful to load GRINDEF without entering the editor.

	From the top level of LISP, (ED) is the same as (ED NIL).

(SPRINT X Y 1)

	SPRINT prints  S-expression  X  in  a  special  format  which
automatically  indents  according to parenthesis level.  Whenever any
sub-S-expression of X cannot fit entirely on the same printing  line,
then  its  sub-S-expressions  are  printed  on  separate  lines  with
matching indentation.  The parameter Y  specifies  the  initial  left
hand  column  indentation.   SPRINT  uses  CHRCT  and  LINELENGTH  to
determine the number of characters remaining on the print line.

(GRINDEF "F1" "F2" ... "Fn")

	GRINDEF is used to print the  definitions  of  functions  and
values  in  DEFPROP  format.   GRINDEF  uses SPRINT to print function
definitions  in  a  highly  readable  format.   GRINDEF  prints   all
SAILON 28.7                    APPENDIX A                         A-2

properties  of  the  identifiers F1, F2, ... Fn which are in the list
%%%L which is initialized to EXPR, FEXPR, VALUE, MACRO and SPECIAL.

Example:   (GRINDEF PLUS)

	(DEFPROP PLUS
	 (LAMBDA (L) (*EXPAND L (QUOTE *PLUS)))

	MACRO)

Description of the Command Structure

	Each  command  to  ALVINE  consists  of  a  single  character
(possibly preceded by a number) followed by a  string  of  arguments.
These  commands  modify  the text string presently occupying ALVINE's
buffer.  When text is introduced to  ALVINE  a  pointer  is  attached
preceding  the  first  object in the buffer.  ALVINE's commands allow
the user to move this pointer  through  the  buffer.   ALVINE's  text
modifying  commands  only  affect  the  string  to  the right of this
pointer.

	In the following command descriptions, "pointer string"  will
mean  the  string  to  the right of the pointer, and "$" will mean an
altmode.  All of the commands which allow  a  repetition  argument  n
assume 1 if n is omitted.

	COMMAND		MEANING			DESCRIPTION

	A		All		Print the buffer string.  No
					attempt is made to make the
					output pretty.

	B		Balanced?	Examines the number of parens
					in the buffer string.  Returns
					the count of left and right
					parens if unbalanced;  otherwise
					replies "BAL".

	nC		Count		For readability, the commands "D",
					"M", ">", "<", "S", and "W", will
					print an initial segment of the
					pointer buffer.  "nC" sets the
					length of this printing segment
					to  n  objects.

	nD		Delete		Deletes the first  n  "objects"
					to the right of the pointer.

	nE		Expunge		Deletes the first n S-expressions
					to the right of the pointer.
SAILON 28.7                    APPENDIX A                         A-3

	F x y:z		File		GRINDEFS the identifiers referred
					to by x on device y using file
					name z.  If X is a list of identifiers,
					then each element of x  is GRINDEFed.
					If x is an atom, then the value of
					x is used as a list of atoms to
					GRINDEF.

	Gx		Get		G will convert an S-expression
					with name  x into ALVINE form, move
					it into the ALVINE buffer and 
					initialize the pointer to the left
					hand end of the buffer.  GET looks
					on the property list of x for the
					first property in the list %%%L
					which is initialized to (FEXPR
					EXPR VALUE MACRO SPECIAL).  %%%L
					may be SETQed globally as desired.
					G also knows about TRACEd functions
					and will handle them properly.
					ALVINE format was described earlier
					as a single level list of atoms
					including the special atoms %LP,
					%RP, %D.

	I		Insert		Insert comes in two flavors:

					1.  I$x$:  insert "x" immediately
					    to the right of the pointer.

					2.  Ix$y$:  insert "y" after the
					    first occurrence (in the pointer
					    string) of the string "x".  "x"
					    may be a complete string or
					    described by ellipsis as "w...z".
					    If "x" is % then "y" is introduced
					    to the editor as the current 
					    string.

	nM		Match		Move the pointer n  S-expressions
					to the right of the current pointer
					position.  If n is negative, move n
					S-expressions left.  If there is no
					such S-expression the pointer is not
					moved and the bell is sounded.

	Px		Put		Converts the editor string from
					ALVINE format to an S-expression and
					puts it back on the property list
					of x  with the appropriate property.
SAILON 28.7                    APPENDIX A                         A-4

	Qx		<follows P>	Same as P except no function name
					need be specified.  Q puts the
					S-expression in the editor buffer
					back on the property list of the
					identifier the last G specified.

	Rx$y$		Replace		Replace the first occurrence of
					"x" by "y".  As with "I", "x" may
					be described elliptically;  and if
					"y" is %, the first occurrence of
					"x" is deleted.

	nSx$		Search		Search for the nth  occurrence of
					the string "x" (in the pointer
					string).  If found, the pointer is
					moved to the beginning of the string
					following that occurrence.  If less
					than n occurrences are located, the
					pointer  is positioned after the
					last such occurrence.  If none are
					found the pointer is not moved.
					If  "x" is not given, i.e., "nS$",
					then the last given search-string
					is used.

	Uxy:z		Unfile		READs and defines the functions
					specified by the list  x  from
					device  y  using  z  as a file name.
					If  x  is an atom, then the value
					of  x  is used as a list function
					names to READ.  U prints the names
					of the functions as it defines them.
					The specified file must be in
					GRINDEF format.

	V		Vomit		Print the first balanced paren
					section to the right of the point
					in pseudo GRINDEF format.

	W		Where?		Prints the beginning of the pointer
					string.

	n> and n<			These commands are dual;  they move
					the string pointer "n" objects to
					the right or left respectively.  
					If "n" is such that either the left
					or right end of the string would be
					exceeded, the pointer is set to
					that extreme and "bell" is typed.

					To reset to the extreme left of
					the string "0<" may be used.
SAILON 28.7                    APPENDIX A                         A-5

					This command returns control to
					LISP.  ALVINE's buffer is left
					intact, and returning to ALVINE,
					the user will find the pointer at
					the left hand end of the old string.

	Bell				Bell may be used during any command
					to return control to ALVINE's
					command-listen-loop.

AN EXAMPLE OF ALVINE

Note:  Bell, space and alt-mode are represented by π, _  and $ respectively.


(ED)

*
I % $(DEFPROP TEST (LAMBDA $;  the string bounded by "$" is introduced to
	ALVINE

*
A$
(DEFPROP TEST (LAMBDA ; print the entire ALVINE buffer
*
B$
2LPS
0 RPS
*
I LAMBDA $ (X) (CAR Y) EXPR) $;  append the string bounded by "$" to the
	buffer

*
B$
4LPS
3 RPS
*
I CAR Y $)$ ;  add the deficient right paren

						;  the following commands 
						   would also have the same effect:
						;  1.  "11<", "I $)$"
						;  2.  "SY$", I $)$
B$
BAL ;
$
V$
(DEFPROP TEST (LAMBDA (X) (CAR Y))EXPR)
*
P TEST$; convert ALVINE string to LISP function
*
↑ ; exit ALVINE
SAILON 28.7                    APPENDIX A                         A-6

T$;  now talking to LISP
T
(TEST (QUOTE(A B)))
Y
UNBOUND VARIABLE-EVAL ; LOSE
(ED)	; re-enter ALVINE,
*
W$
(DEFPROP TEST; "G" need not be executed since the buffer is always left intact.
*
R X $ Y$
*
P TSπ ; flush incorrect "put" command by typing bell. (π)
*
PTEST $ ; redefine TEST
*
↑
(TEST (QUOTE(A B)))$ ; try again
A		     ; win
(ED)
*
5 > $
(Y)
*
5C $ ; change print count
*
M $
(CAR Y))
*
E $
*
A $ 
(DEFPROP TEST (LAMBDA (Y))EXPR)
*
W $
)EXPR)
*
0 < $
π(DEFPROP TEST(
*
R TEST ...) $%$
*
A $
(DEFPROP)EXPR) ; same effect by:
		 1.  "SDEFPROP $", "6D"
*
SAILON 28.7                    APPENDIX B                         B-1

                             APPENDIX B

                           ERROR MESSAGES

	The LISP interpreter checks for  some  error  conditions  and
prints  messages  accordingly.   Many  erroneous  conditions  are not
tested and result in either the wrong error  message  at  some  later
time,  or no error message at all.  In the latter case the system has
screwed you (or itself) without complaining.

	When error messages are printed, it is usually  difficult  to
determine the function which caused the error and the functions which
called it.  In this situation, (BAKGAG T) will turn on the  BACKTRACE
flag  which  causes  the heirarchy of function calls to be printed as
described in the next section.

	The following is an alphabetical listing of  error  messages,
their  cause,  and  in some cases, their remedy.  Some error messages
print two lines, such as:

	FOO
	UNBOUND VARIABLE - EVAL

These  messages  are  described  last  in the listing, and are of the
form:

	X	<message>

BINARY PROGRAM SPACE EXCEEDED

	ARRAY, EXARRAY, or LAP has  exceeded  BINARY  PROGRAM  SPACE.
	ALLOCATE more BPS next time.

CAN'T EXPAND CORE

	INPUT, OUTPUT, LOAD, or ED failed to expand core.   Your  job
	 is too large.

CAN'T FIND FILE - INPUT

	The input file was not found.  You probably  forgot  to  give
	the file name extension, or a legal name list.

DEVICE NOT AVAILABLE

	INPUT or OUTPUT found the specified device unavailable.  Some
	other job is probably using it.

DIRECTORY FULL

	The directory of the output device is full.
SAILON 28.7                    APPENDIX B                         B-2

DOT CONTEXT ERROR

	READ does not like dots adjacent to parens or other dots.

FILE IS WRITE-PROTECTED

	OUTPUT found that the specified file is write-protected.

FIRST ARGUMENT NON-ATOMIC - PUTPROP

	An attempt was made to PUTPROP onto a non-identifier.

GARBAGED OBLIST

	Some  member  of  the  OBLIST  has been garbaged.  You are in
	trouble.

ILLEGAL DEVICE

	INPUT or OUTPUT was attempted to either a non-existent device
	or to a device  of the  wrong type.   I.e.,  INPUT  from  the
	lineprinter.

ILLEGAL OBJECT - READ

	READ objects to syntactically incorrect S-expressions.

INPUT ERROR

	Bad data was read from the selected device.

MORE THAN ONE S-EXPRESSION - MAKNAM

	MAKNAM  and  READLIST  object to a list which constitutes the
	characters for more than one S-expression.

NO FREE STG LEFT

	All free storage is bound to the OBLIST and  protected  cells
	(such as list ARRAY cells), and bound variables on either the
	REGULAR or SPECIAL pushdown list.  Unbinding to the top level
	will  usually  release the storage.  If you are in a bind for
	more free storage, try to REALLOC as described in APPENDIX C.

NO FULL WORDS LEFT

	All full words are being used for print  names  and  numbers.
	The problem and its solution are similar to FREE STG.

NO I/O CHANNELS LEFT
SAILON 28.7                    APPENDIX B                         B-3

	INPUT or OUTPUT failed to find a free I/O channel.  There  is
	a maximum of 14 active I/O channels.
NO INPUT - INC

	n attempt was made to select a channel for input with INC
	which was not initialized with INPUT.

NO LIST - MAKNAM

	MAKNAM and READLIST object to an empty list.

NO OUTPUT - OUTC

	An attempt was made to select a channel for output with OUTC
	which was not initialized with OUTPUT.

NO PRINT NAME - INTERN

	INTERN found a member of the OBLIST which has no print  name.
	You are in trouble.

OUTPUT ERROR

	Data was improperly written on the selected output device.
	Possibly a write-locked DECTAPE.

OVERFLOW

	Some arithmetic function caused overflow - either fixed or
	floating.

PDL OVERFLOW FROM GC - CAN'T CONTINUE

	There is not enough regular pushdown list to  finish  garbage
	collection.   You  lose.   Try  to  REALLOC  as  described in
	APPENDIX C.

READ UNHAPPY - MAKNAM

	MAKNAM and READLIST object to a list which is not an entire
	S-expression.

REG PUSHDOWN CAPACITY EXCEEDED SPEC PUSHDOWN CAPACITY EXCEEDED

	A  pushdown  list  has overflowed.  This is usually caused by
	non-termination of recursion.  Sometimes you need to ALLOCATE
	or REALLOC more pushdown list.

TOO FEW ARGUMENTS SUPPLIED - APPLY  TOO  MANY  ARGUMENTS  SUPPLIED  -
APPLY
SAILON 28.7                    APPENDIX B                         B-4

	APPLY  checks  all  calls  on  interpreted  functions for the
	proper number of arguments.

X MADE ILLEGAL MEMORY REFERENCE

	The  function  X  referred  to  an  illegal address.  Usually
	caused by taking the CAR or CDR of an atom or number.

X NON-NUMERIC ARGUMENT

	Arithmetic functions require that their arguments be numbers.

X PROGRAM TRAPPED FROM

	An illegal instruction was executed in function X.

X UNBOUND VARIABLE - EVAL

	EVAL tried to evaluate an identifier and found that it had no
	value.  You probably forgot to QUOTE some atom to  initialize
	it.

X UNDEFINED COMPUTED GO TAG IN

	A GO in some compiled function had an undefined label.

X UNDEFINED FUNCTION X UNDEFINED FUNCTION - APPLY

	The function X is not defined.

X UNDEFINED PROG TAG - GO

	A GO in some interpreted function had an undefined label.
SAILON 28.7                    APPENDIX C                         C-1

                             APPENDIX C

                          MEMORY ALLOCATION

	The LISP 1.6 system has many different areas  of  memory  for
storing  data  which  can  independently  vary  in  size.   Some LISP
applications demand larger allocations for these areas  than  others.
To allow users to adjust the sizes of these areas to their own needs,
a memory allocation procedure exists.

C.1  Summary of Storage Allocation Areas

BINARY PROGRAM SPACE		Area for compiled functions and arrays.
FREE STORAGE			Area for LISP nodes.
FULL WORD SPACE			Area for print names and numbers.
BIT TABLES			Area for the garbage collector.
REGULAR PUSHDOWN LIST		Area for all function calls and non-
				  special variables in compiled functions.
SPECIAL PUSHDOWN LIST		Area for interpreted variables and special
				  variables.
EXPANDED CORE			Area for I/O buffers, ALVINE, LOADER, and
				  any loaded programs.

			TOP OF CORE
	     _____________________________________
	     |					  |
	     |		EXPANDED CORE		  |
	     |____________________________________|
	     |					  |
	     |	   SPECIAL PUSHDOWN LIST	  |
	     |____________________________________|
	     |					  |
Memory map   |      REGULAR PUSHDOWN LIST	  |
for the LISP |____________________________________|
1.6 system   |					  |
	     |		 BIT TABLES		  |
	     |____________________________________|
	     |					  |
	     |	       FULL WORD SPACE		  |
	     |____________________________________|
	     |					  |
	     |		FREE STORAGE		  |
	     |____________________________________|
	     |					  |
	     |	   BINARY PROGRAM SPACE		  |
	     |____________________________________|
	     |					  |
	     |	    LISP INTERPRETER		  |
	     |____________________________________|
	     		BOTTOM OF CORE
SAILON 28.7                    APPENDIX C                         C-2

C.2  ALLOCATION

	When the LISP system is initially started, it asks  the  user
to specify the size of each of its various spaces as follows.

ALLOC?
FULL WDS=
BIN.PROG.SP=
SPEC.PDL=
REG. PDL=
HASH=

	There are two basic responses to any of these questions: 

	1) A space will cause the default value to be used.  
	2) A number ended by a space cause the number to be used.

	The default sizes of the later four spaces  are  2000,  1000,
1000, and 77 octal words respectively.  The default for full words is
400 octal plus a small fraction of free storage.    Free  storage  is
thus allocated almost all of what is left.



C.3  REALLOC

	If you have an existing LISP core image  but  have  exhausted
one of the storage areas, it is possible to increase the size of that
area using the reallocation procedure.  First, expand core  with  the
time  sharing  system  command  CORE  and then re-enter the LISP core
image with the START command. For example, if the original core  size
was 20K, you could increase it by 4K as follows:

↑C
.CORE 24
.START
*

When you reallocate a core image, all additional  core  is  allocated
as follows:

	1/4 for full word space
	1/64 for each pushdown list,
	the remainder to free storage and bit tables.

C.4  Binary Program Space

	The  reallocation  procedure  does  not  increase the size of
binary program space.  However, it is  possible  to  increase  binary
program space by expanding core with the CORE (C) command and setting
BPORG and BPEND to the beginning and end  of  the  expanded  area  of
core.  For example, if you now have 32K of core and want 4K more BPS,
SAILON 28.7                    APPENDIX C                         C-3

do the following:

	(EXCISE)	to eliminate IO buffers
	↑C
	.CORE 36
	.START
	*(SETQ BPORG (TIMES 32. 1024.))
	*(SETQ BPEND (PLUS BPORG 4095.))

Note:	If you  use  the   reallocation    procedure   after   having
	expanded core   for  any  purpose,  it  will  reallocate  this
	additional core for its own  purposes,  thus  destroying  the
	contents of the expanded core.

The following are the standard causes for expansion of core:

	1)  using I/O channels.
	2)  using the LOADER -(LOAD).
	3)  expanding core for more binary program space.
	4)  using (ED).
SAILON 28.7                    APPENDIX D                         D-1

                             APPENDIX D

                         GARBAGE COLLECTION


	All LISP  systems  have  a  function  known  as  the  garbage
collector.  This function analyzes the entire state of list structure
which is pointed to by either the OBLIST, the regular pushdown  list,
the  special  pushdown  list,  list  arrays,  and a few other special
cells.   By recursively marking all  words  on  free  and  full  word
spaces  which  are  pointed  to  in  this  manner,  it is possible to
determine which words are not pointed to and are  therefore  garbage.
Such  words  are  collected together on their respective free storage
lists.

(GC)

	GC  causes  a  garbage  collection  to occur and returns NIL.
Normally, a garbage collection occurs only when either free  or  full
word space has been exhausted.

(GCGAG X)	flag = NIL initially.

	GCGAG sets a special flag in the interpreter to the value  of
X,  and  returns  the previous setting of the flag.  When any garbage
collection occurs, if the flag ≠ NIL, then the following is printed:

	either		FREE STORAGE EXHAUSTED
	    or		FULL WORD SPACE EXHAUSTED
	    or		nothing

	followed by	x FREE STORAGE, y FULL WORDS AVAILABLE

where x and y are numbers in octal.

(SPEAK)

	SPEAK  returns  the  total  number  of CONSes which have been
executed in this LISP core image.

(GCTIME)

	GCTIME  returns  the  number  of  milliseconds LISP has spent
garbage collecting in this core image.

	It  is possible to determine the lengths of the free and full
word free storage lists by:

	(LENGTH (NUMVAL 15↓8))	= length of free storage list
	(LENGTH (NUMVAL 16↓8))	= length of full word list
SAILON 28.7                    APPENDIX E                         E-1

                             APPENDIX E

           COMPILED FUNCTION LINKAGE AND ACCUMULATOR USAGE

	This  appendix  is  intended  to  explain  the  structure  of
compiled functions, function  calls,  and  accumulator  usage.   This
discussion  is  relevant  only if one intends to interface hand coded
functions or possibly functions generated by another system (such  as
FORTRAN)  with  the  LISP  system.   In  such  a  case,  it is highly
recommended that one examine the  LAP  code  generated  by  the  LISP
compiler for some familiar functions.

                       ACCUMULATOR USAGE TABLE


  s means "sacred" to the interpreter
  
  p means "protected" during garbage collection

	NIL  = 0	s,p	Header for the atom NIL.
	A    = 1	p	Results  from  functions, 1st  arg to          
					functions
	B    = 2	p	2nd arg
	C    = 3	p	3rd arg
	AR1  = 4	p	4th arg	
	AR2A = 5	p	5th arg
	T    = 6	p	used for LSUBR linkage
	TT   = 7	p
	T10  = 10	p	rarely used in the interpreter
	S    = 11		rarely used in the interpreter
	D    = 12	
	R    = 13
	P    = 14	s,p	regular pushdown list pointer
	F    = 15	s,p	free storage list pointer
	FF   = 16	s,p	full word list pointer
	SP   = 17	s,p	special pushdown list pointer.

TEMPORARY STORAGE

	Whenever a LISP function is called from a compiled  function,
it  is  assumed that all accumulators from 2 through 13 are destroyed
by the function unless  it  is  otherwise  known.   Therefore,  local
variables  and  parameters  in a compiled function should be saved in
some protected cells such as the regular pushdown list.  The PUSH and
POP instructions are convenient for this purpose.

SPECIAL VARIABLE BINDINGS

	Special variables in compiled functions are bound to  special          
cells by:
SAILON 28.7                    APPENDIX E                         E-2

			PUSHJ P, SPECBIND
			0 n↓1, var↓1
			0 n↓2, var↓2
			    ...
			start of function code.

SPECBIND saves the previous values of var↓i on the  special  pushdown
list  and  binds  the contents of accumulator n↓i to each var↓i.  The
var↓i must be pointers to special cells of  identifiers.   Any  n↓i=0
causes the var↓i to be bound to NIL.

	Special variables are restored to their previous values by:

			PUSHJ P,SPECSTR

which stores the values previously saved on the special pushdown list
in the appropriate special cells.

NUMBERS

	To convert the number in A from its  LISP  representation  to
machine representation use:

			PUSHJ P,NUMVAL

which returns the value of the number in  A,  and  its  type  (either
FIXNUM or FLONUM) in B.

	To convert the number in A from its machine representation to
LISP representation use either:

		PUSHJ P,FIX1A		for FIXNUMS
	or	PUSHJ P,MAKNUM		with type in B.

Both of the above functions return the LISP number in A.

FUNCTION CALLING UUOS

	To  allow  ease  in  linking,  debugging,  and  modifying  of
compiled functions, all compiled functions call other functions  with
special  opcodes  called  UUOs.  Several categories of function calls
are distinguished:

	1)  Calls of the form (RETURN (FOO X)) are called terminal calls
	    and essentially "jump" to FOO.

	2)  Calls of the form (F X) where F is a computed function name
	    or functional argument is called a functional call.

The function calling UUOS are:

					non-terminal	terminal
SAILON 28.7                    APPENDIX E                         E-3

		non-functional		CALL n,f	JCALL n,f
		    functional		CALLF n,f	JCALLF n,f

where  f is either the address of a compiled function or a pointer to
the identifier for the function, and n specifies the type of function
being called as follows:

	n = 0 to 5		specifies a SUBR call with n arguments
	n = 16			specifies a LSUBR call
	n = 17			specifies a FSUBR call.

	The function calling UUOs are defined in MACRO by:

	OPDEF CALL [34B8]
	OPDEF JCALL [35B8]
	OPDEF CALLF [36B8]
	OPDEF JCALLF [37B8]

(NOUUO X)	flag = T initially

	NOUUO sets a special flag in the  compiled  function  calling
mechanism  to  the value of X and returns the previous setting of the
flag. Compiled functions initially call other functions with function
calling  UUOs which "trap" into the UUO mechanism of the interpreter.
Ordinarily, such function calls involve searching the  property  list
of  the  function  being called for the functional property, and then
(depending on whether the function is compiled  or  an  S-expression)
the function is called.

	If the NOUUO flag is set to NIL, then the overhead in calling
a compiled function from a compiled function  can  be  eliminated  by
replacing  the  CALL by PUSHJ and JCALL by JRST. CALLF and JCALLF are
never changed.

	However, there are  several  dangers  and  restrictions  when
using (NOUUO NIL).  Once the UUO's have been replaced by PUSHJ's then
it is not possible to redefine or TRACE the  function  being  called.
It  is therefore recommended that compiled functions be debugged with
(NOUUO T).

SUBR LINKAGE

	SUBRs are compiled EXPRs which are the most  common  type  of
function.  Consequently,  considerable  effort  has been made to make
linkage to SUBRs efficient.

	Arguments to SUBRs are supplied in accumulators 1 through  n,
the first argument in 1.  There is a maximum of 5 arguments to SUBRs.

	To  call  a SUBR from compiled code, use call n,FUNC, where n
is the number of arguments, and call is the appropriate UUO.
SAILON 28.7                    APPENDIX E                         E-4

	The result from a SUBR is returned in A(= 1).

FSUBR LINKAGE

	FSUBRs receive one argument in A and return their  result  in
A. FSUBRs which use the A-LIST feature call:

			PUSHJ P, *AMAKE

which generates in B a number  encoding  the  state  of  the  special
pushdown  pointer.   To call a FSUBR, use call 17, FUNC, here call is
the appropriate UUO.

LSUBR LINKAGE

	LSUBRs are  similar  to  SUBRs  except  that  they  allow  an
arbitrary  number  of  arguments  to be passed.  To call a LSUBR, the
following sequence is used:

		PUSH P, [ret]	;return address
		PUSH P, arg1	;1st argument
		    ...
		PUSH P, argn	;nth and last argument
		MOVNI T,n	;minus number of arguments
		call 16,func	;the appropriate UUO
	ret:			;the LSUBR returns here

When a LSUBR is entered, it executes:

		JSP 3,*LCALL

which initializes the LSUBR.  A will contain n.  The ith argument
can be referenced by:

		MOVE A, -i-1(P)

Exit from an LSUBR with

		POPJ P,

which returns to *LCALL to restore the stack.
SAILON 28.7                    APPENDIX F                         F-1

			APPENDIX F

		     THE LISP COMPILER

		     by Whitfield Diffie


	The LISP compiler is a  LISP  program  which  transforms  LISP
functions  defined by S-expressions into LAP assembly code.  This can
be loaded into binary program space by LAP (LISP Assembly Program), a
combined  assembler  and loader, which produces absolute machine code
in core.

	Compiled functions are approximately twenty times as fast  as
interpreted  functions.   Compiled functions also take up less memory
space  and  relieve  the  garbage  collector  from  marking  function
definitions.  In a very large system of functions, this last point is
particularly significant.

	The LISP compiler exists as the system program COMPLR, and is
called  by  the incantation `R COMPLR.' Once started, it is spoken to
in the same dialect as any other LISP.

USE OF THE COMPILER 

(COMPL . "FILENAME - LIST") 

	The  function  COMPL takes as arguments an assortment of file
names and device names in precisely the  same  way  as  the  function
DSKIN.   The  default  device  to be used for input in the event that
none is supplied in the argument sequence is given by  the  value  of
the  variable  INDEV.   There is no provision for specification of an
output device in the argument sequence.  If the output is  wanted  on
some device other than the user's disk area, the variable OUTDEV must
be set to indicate this desire.  All error messages and comments  are
normally  directed  to  the teletype.  They can be sent to some other
device by setting  the  variable  LISTING.   Files  produced  by  the
compiler have the filename extension LAP.

Examples: 

	(COMPL FOO SYS: TRACE) 

	will compile the file FOO from the users disk area 
	and the file TRACE from the system area to produce 

	the files FOO.LAP and TRACE.LAP on the users disk 
	area. 

	(SETQ INDEV (QUOTE DTA2:)) (SETQ OUTDEV (QUOTE (2,DAV))) 
	(SETQ LISTING (QUOTE (DSK: CMPMSG))) 
	(COMPL HAT SYS: SMILE) 
SAILON 28.7                    APPENDIX F                         F-2

	will compile the file HAT from DTA2: and the file 
	SMILE from SYS: to produce the files HAT.LAP and
	SMILE.LAP on the disk area [2,DAV].  All compiler 
	messages will appear as the file CMPMSG on the 
	user's disk area. 

PREPARING FILES FOR COMPILATION 

	In preparing a file for compilation there are several  things
that the user is well advised to bear in mind.

1)  All  normal  function  defining  functions  are acceptable to the
compiler.  Functions defined  by  DE,  DF,  and  DEFPROP, and  macros
defined by DEFPROP or DM, will be correctly understood.

2) Any function which is unknown to the compiler  when  it  is  first
obliged  to generate a call thereto, will be assumed to be an EXPR or
SUBR.   If a file contains a function of  any  other  type  which  is
called by a function defined earlier in the file, it must be declared
to the compiler with one of the statements:   (DEFPROP fun T  *FSUBR)
or  (DEFPROP  fun T *LSUBR) so that the compiler will know how to set
up its arguments.

3)  Any  variable  which occurs free in any function must be declared
SPECIAL prior to the definition  of  any  function  which  binds  it.
This  may  be  done  with  a  statement  of  the form `(DEFPROP var T
SPECIAL).'

4) As macros are functions which are  actually  executed  at  compile
time,  their  definitions  must  occur  earlier  in the file than any
function which appeals to them.  If this is not done, the macro  will
be mistaken for an undefined EXPR.

COMPILER MESSAGES 

	As the compiler goes about its business, it will make various
comments and complaints about your code.

1) As the compilation of each function is completed, its name will be
typed on the teletype without carriage  return.   Any  other  message
will be stood off by carriage returns above and below.

2) Whenever the compiler discovers a free variable which has not been
declared special, it declares it.  At the  end  of  any  function  in
which it found such variables it will print out the message:

(SPECIAL var1 var2 etc.).

3) If a prog variable is unused in a function the compiler will print
the message  (UNUSEDPROGVAR  varname).   It  will  also  declare  the
variable special on the theory that if it was not used there, it must
have been used somewhere else.
SAILON 28.7                    APPENDIX F                         F-3

4) Many minor errors in user code will unfortunately  go  undetected.
Any serious error will produce the message *USER ERROR* followed by a
description of what was wrong.  This will halt the  compiler.      

5) The  error  message *COMPILER ERROR* indicates a bug in the compiler.
Please report this to Whitfield Diffie.

6) When the compiler has finished, it will type out the name  of  the
file,  the  number  of  words  of  code  produced and the time taken.
Following these will be lists of any functions called but not defined
in the file and any auxiliary functions the compiler generated.

USING COMPILED CODE 

	As LAP is self loading, the loading of compiled files is  the
same  as for interpreted functions.  The allocations must be changed,
however, to reflect the passage of the  code  from  free  storage  to
binary  program space.  The correct size of the latter is the size of
the program as stated at the end of compilation, plus the  length  of
lap which is about 500(8) words.

	The  following  example  illustrates  various  aspects of the
compiler's behavior.   We show a collection  of  functions,  the  LAP
code  generated from it, and the comments made by the compiler in the
process.

THE FUNCTIONS 
	
(DM FIRST (L) (CONS @ CAR (CDR L))) ;macro defined at beginning 
	
(DEFPROP IT T SPECIAL) 		;special declaration 
	
(DEFPROP MAPCONS 		;the internal lambda 
 (LAMBDA (IT LIST) 		;becomes a separate function 
  (MAPCAR (FUNCTION 		;thus the variable IT must  
	   (LAMBDA (X) 		;  be made special
		   (CONS IT X))) 
	  LIST)) 
 EXPR) 
	
(DEFPROP COUNTM 	
 (LAMBDA (SEXPR) 
  (PROG (COUNT) 		;the variable COUNT has not been 
	(SETQ COUNT 0) 		;declared special and will be treated 
	(COUNT1 SEXPR) 		;as local 
	(RETURN COUNT))) 
 EXPR) 
 
(DE COUNT1 (SS) 
 (COND ((ATOM SS) NIL) 
       (T (INCR COUNT) 		;here it is discovered to be special 
	  (COUNT1 (FIRST SS)) 	;but too late 
SAILON 28.7                    APPENDIX F                         F-4

	  (COUNT1 (CDR SS))))) 
	
(DE SCALE (NO) 		;this variable is found to 
 (TIMES NO SCALEF)) 	;be special, in good time 
 
(DF SETQQ (L) (SET (CAR L) (CADR L))) 
	
(SETQ SCALEF 3) 	;this will be output unchanged 
 
THE RESULTING LAP

;note that the macro definition and the special declaration have 
;been gobbled up by the compiler.  

(LAP MAPCONSG0220 SUBR)  	;this is the function 
	(MOVE 2 (SPECIAL IT))  	;generated by the 
	(JCALL 2 (E XCONS))  	;internal lambda 
	NIL  			;in MAPCONS 
 
(LAP MAPCONS SUBR)  
	(JSP 6 SPECBIND)  
	(0 2 (SPECIAL IT))  
	(MOVEI 1 (QUOTE MAPCONSG0220))  
	(CALL 2 (E MAPCAR))  
	(JRST 0 SPECSTR)  
	NIL  

(LAP COUNTM SUBR)  
	(PUSH P 1)  	;this code is in error 
	(PUSH P (C 0 0 (QUOTE 0) 0))  	;due to the failure 
	(CALL 1 (E COUNT1))  		;to make COUNT special 
	(MOVE 1 0 P)  
	(SUB P (C 0 0 2 2))  
	(POPJ P)  
	NIL  
 
(LAP COUNT1 SUBR)  
	(PUSH P 1)  
	(CALL 1 (E ATOM))  
	(JUMPE 1 G0229)  
	(MOVEI 1 (QUOTE NIL))  
	(JRST 0 G0228)  
G0229 	(MOVE 1 (SPECIAL COUNT))  	;reference to the special 
	(CALL 1 (E INCR))  		;variable COUNT, which has 
	(HLRZ@ 1 0 P)  			;not been bound properly 
	(CALL 1 (E COUNT1))  
	(HRRZ@ 1 0 P)  
	(CALL 1 (E COUNT1))  
G0228 	(SUB P (C 0 0 1 1))  
	(POPJ P)  
	NIL  
 
SAILON 28.7                    APPENDIX F                         F-5

(LAP SCALE SUBR)  
	(MOVE 2 (SPECIAL SCALEF))  	;SCALEF is a free variable 
	(JCALL 2 (E *TIMES))  		;correctly detected 
	NIL  

(LAP SETQQ FSUBR)  
	(HRRZ@ 2 1)  
	(HLRZ@ 2 2)  
	(HLRZ@ 1 1)  
	(JCALL 2 (E SET))  
	NIL  
 
(SETQ SCALEF 3)  	;this was unchanged by compilation 
 
THE COMPILER'S OPINION 

MAPCONSG0220 MAPCONS COUNTM 
(SPECIAL COUNT)		;special found too late
COUNT1 
(SPECIAL SCALEF)  	;special found in time

SCALE SETQQ  
 
(CMP . CMP) COMPILED 41 WORDS 3 CONSTANTS 1 SECONDS  
 
UNDEFINED FUNCTIONS  
INCR  
 
GENERATED FUNCTIONS  
MAPCONSG0220  
SAILON 28.7                    APPENDIX G                         G-1

                             APPENDIX G

                      THE LISP ASSEMBLER - LAP

	LAP is a primitive assembler designed to load the output of the
compiler.  Normally, it is not necessary to use LAP for any other purpose.
LAP is self loading.

	The format of a compiled function in LAP is:

		(LAP name type)

		<sequence of LAP instructions>

		NIL

where name is the name of the function, and type is either SUBR, LSUBR,
or FSUBR.

	A LAP instruction is either:

	1.  A label which is a non-NIL identifier.

		2.  A list of the form

		    (OPCODE AC ADDR INDEX)

		    a.  The index field is optional.

		    b.  The opcode is either a PDP-6/10 instruction
		which is defined to LAP and optionally suffixed
		by @ which designates indirect addressing, or
		a number which specifies a numerical opcode.

		    c.  The AC and INDEX fields should contain a number
		from 0 to 17, or P which designates register 14.

		    d.  The ADDR field may be a number, a label, or a
		list of one of the following forms:

			(QUOTE S-expression)	to reference list structure.
		
		(SPECIAL x)		to reference the value of
					  identifier x.

			(E f)			to reference the function f.

			(C OPCODE AC ADDR INDEX) to reference a literal constant.

For example, the function ABS could be defined:














SAILON 28.7                    APPENDIX G                         G-2

			(LAP ABS SUBR)
			(CALL 1 (E NUMVAL))
			(MOVMS 0 1)
			(JCALL 2(E MAKNUM))
			NIL

SAILON 28.7                    APPENDIX H                         H-1

                             APPENDIX H

                             THE LOADER

	A    modified    version    of    the    standard    PDP-6/10
MACRO-FAIL-FORTRAN loader is available for use in LISP.  One can call
the loader into a LISP core image at any time by executing:

			(LOAD X)

When a * is typed, you are in the (LOAD X)  loader,  and  the  loader
command strings are expected.  As soon as an altmode  is  typed,  the
loader finishes and exits back to LISP.

	The loader is placed in expanded  core.   If  X  =  NIL  then
loaded  programs  are placed in expanded core, otherwise (if X ≠ NIL)
they are placed in BINARY PROGRAM SPACE.

	The loader removes itself  and  contracts  core  when  it  is
finished. In the following discussion a "RELOC" program will refer to
any program which is suitable  for  loading  with  the  loader.   The
output of FORTRAN, MACRO or FAIL is a RELOC program.

(EXCISE)

	EXCISE  contracts  core to its length after ALLOCATION  or the
	last START. This removes I/O buffers, and all RELOC programs.

(*GETSYM S)

	*GETSYM searches the DDT symbol table for the symbol S and if
found returns its value, otherwise it returns NIL.

(GETSYM "P" "S↓1" "S↓2" ... "S↓n")

	GETSYM searches the DDT symbol table for each of the symbols S↓i
and places the value on the property list of S↓i under property P.

Example:  (GETSYM SUBR DDT)

	This causes DDT to be defined as a SUBR located at the  value
of the symbol DDT.

Note:	In  order  to  load the symbol table, either /S or /D must be
	typed to the loader.  Symbols which are declared INTERNAL are
	always in the symbol table without the /S or /D.  In the case
	of multiply defined symbols, i.e., a symbol used in more than
	one   RELOC   program,   a  symbol  declared  INTERNAL  takes
	precedence, the last symbol otherwise.

(*PUTSYM S V)
SAILON 28.7                    APPENDIX H                         H-2

	*PUTSYM  enters  the  symbol S into the DDT symbol table with
value V.

(PUTSYM "X↓1" "X↓2" ..."X↓n")

	PUTSYM  is used to place symbols in the DDT symbol table.  If
X↓i is an atom then the symbol X↓i is placed in the symbol table with
its  value pointing to the atom X↓i.  If X↓i is a list, the symbol in
(CAR X↓i) is placed in the symbol table with its  value  (EVAL  (CADR
X↓i)).   PUTSYM  is  useful  for  making  LISP  atoms, functions, and
variables available to RELOC programs.  Symbols must be defined  with
PUTSYM before the LOADER is used.

Examples:	(PUTSYM BPORG (VBPORG (GET (QUOTE BPORG)(QUOTE VALUE))))

defines the identifier BPORG and its  value  cell  VBPORG.   A  RELOC
program can reference the value of BPORG by:

			MOVE X,VBPORG

		(PUTSYM (MAPLST (QUOTE MAPLST)) (NUMBERP (QUOTE NUMBERP)))
		(PUTSYM (MEMQ (GET(QUOTE MEMQ) (QUOTE SUBR))))

A RELOC program would call these functions as follows:

		CALL 2,MAPLST
		CALL 1,NUMBRP
		PUSHJ P,MEMQ or CALL 2,MEMQ

	An example of a  simple  LISP  compatible  MACRO  program  to
compute square roots using the FORTRAN library.

	TITLE TEST
	P=14
	A=1
	B=2

EXTERN MAKNUM,NUMVAL,SQRT,FLONUM

LSQRT:	CALL 1, NUMVAL
	MOVEM A,AR1
	MOVE A,[XWD 0,BLT1]; SAVE THE AC'S
	BLT A,BLT1+17
	JSA 16,SQRT
	JUMP 2,AR1 ;SOP TO FORTRAN
	MOVE 0,AR1
	MOVE A,[XWD BLT1 ,0]
	BLT A,17
	MOVE A,AR1
	MOVEI B,FLONUM
	JCALL 2,MAKNUM
AR1:	0
SAILON 28.7                    APPENDIX H                         H-3

BLT1:	BLOCK 20

END
SAILON 28.7                    APPENDIX I                         I-1

                             APPENDIX I

               BIGNUMS - ARBITRARY PRECISION INTEGERS


	LISP numbers have always been second class citizens,  in  the
sense  that  unlike  strings (print names) numbers have had a maximum
length.  In the PDP-6/10 LISP system there is an  optional  arbitrary
precision  integer  package which extends the length of LISP integers
from 36-bits to any length.

	To load the BIGNUM system, execute the following at  the  top
level of LISP:

		*(INC(INPUT SYS: (BIGNUM.LSP)))
		<SEQUENCE OF OUTPUT>
		*(LOAD T)*SYS:BIGNUM$
		<LOADER TYPES BACK>
		*(APNINIT)

and then your core image will  perform  arbitrary  precision  integer
operations  using  the  standard LISP arithmetic functions which were
redefined by APNINIT.

	It is possible to load the BIGNUM package at any time  unless
you  have  already  executed  compiled functions with (NOUUO NIL), in
which case you must reconstruct your core image.
SAILON 28.7                    APPENDIX J                         J-1

                   A USER MODIFIABLE LISP SCANNER

                            by Lynn Quam

	LISP uses a table driven scanner, whose table may be modified
by  the  user  for  the  purpose  of  implementing scanners for other
languages. For simplicity, the functions for constructing the scanner
table  initially  give  an  ALGOL  type  scanner,  that  is the ALGOL
definitions for identifiers, strings and numbers (except  for  powers
of  ten).   The  ALGOL  table  may  be  modified  by using additional
functions to include additional characters  in  identifiers,  and  to
specify delimiters for strings.

J.1  FORMAL DEFINITIONS

J.1.1  Identifiers

Syntax:

comment		::=  (a comment-start followed by any sequence of
			characters ending in a comment-end)

digit		::=  "0" | "1" | ... | "9"
letter		::=  "A" | "B" | ... | "Z" | "a" | "b" | ... | "z" |
			extra-letter
character	::=  (any ASCII character other than null, rubout,
			and comment-start)
delimiter	::=  (any character not a letter and not a digit)
		::=  letter
		::=  identifier digit
		::=  identifier letter
		::=  slashified character
		::=  identifier slashified character

Semantics:

	In the above syntax, underlined symbols can be  specified  by
the  user.  For instance, comment-start and comment-end could both be
specified to be double quote (").  If  it  is  desirable  to  include
dollar   and  percent  signs  in  identifiers,  then  both  of  these
characters should be extra-letters.  Slashifiers make it possible  to
include  any  delimiter  in  an identifier.  For example, if question
mark is the slashifier  (?)  and  it  is  desirable  to  include  the
character (+) in the identifier V as V+, then one should slashify the
plus:  V?+.

J.1.2  Strings

Syntax:

string		::=  (a string-start followed by any sequence of
			characters ending in a string-end)
SAILON 28.7                    APPENDIX J                         J-2

Semantics:

	String-start and string-end are specifiable.

J.1.3  Numbers

Syntax:

	Same  as specified in Chapter 4, except that leading signs (+
or -) in numbers are treated as delimiters.

J.2  DESCRIPTIONS OF THE SCANNER MODIFYING FUNCTIONS

	In  the  following descriptions, all characters are specified
by their numerical ASCII value.  For example, in octal, blank  is  40
and A is 101.

(SCANINIT comment-start comment-end string-start string-end slashifier)
	SCANINIT modifies  the  LISP  scanner  to  be  an  ALGOL-type
scanner  with  special delimiters for comments and strings.  SCANINIT
must be called before any of the other scanner functions.

(IGNORE x)
	LETTER  specifies to the scanner that x is not to be returned
as a delimiter from scan, but instead will be  ignored.   However,  x
will  still  function  as a separator between identifier and numbers.
For example, carriage-return, line-feed, tab  and  blank  are  useful
characters to ignore as delimiters.

(LETTER X)
	Letter specifies to the scanner that X is an extra-letter,
and thus allows X to be in an identifier.

(SCAN)
	SCAN reads an atom or delimiter and sets  the  value  of  the
global  variable  SCANVAL  to  the  value  read, and returns a number
corresponding to the syntactic type read as follows:

	Syntactic type	Value of SCAN	Value of SCNVAL

	identifier		0	the uninterned identifier
	string			1	the string
	number			2	the value
	delimiter		3	the ASCII value of the
					  delimiter.

(SCANSET)
	SCANSET  modifies  the  LISP scanner in READ according to the
user specifications.  Evaluate (SCANSET) before calling SCAN.
SAILON 28.7                    APPENDIX J                         J-3

(SCANRESET)
	SCANRESET  unmodifies  the  LISP scanner to its normal state,
and must be called before READ will work properly again once  SCANSET
is used.  Use INITFN to call SCANSET after errors.

J.3  USING THE MODIFIABLE SCANNER

	The scanner modifying functions are not a normal part of  the
LISP  system  and  must  be explicitly loaded into a LISP core image.
The following steps indicate how  to  provide  the  proper  interface
between  LISP  and  the scanner, load the scanner, and initialize the
scanner tables.

	(SETQ SCNVAL NIL)
	(PUTSYM (SCNVAL (GET (QUOTE SCNVAL)(QUOTE VALUE))))

	(LOAD) SYS:SCAN$

	(GETSYM SUBR SCANINIT LETTER IGNORE SCAN SCANSET
		SCANRESET)

	(SCANINIT 21 73 42 42 45)
	<this makes comments start with ⊃ and with semicolon,
	 strings start and end with double quotes ("), and
	 percent (%) is the slashifier>

	To  use  the  scanner,  one must first call the SCANSET. Once
SCANSET has been called, the normal  LISP  function  READ  no  longer
behaves  in  a  normal  fashion, since READ will now use the modified
scanner tables.  Care must be taken to call SCANRESET before  calling
READ.
SAILON 28.7                    APPENDIX K                         K-1

                             APPENDIX  K

                              SOS-LINK


                         by Whitfield Diffie

	The SOSLINK program is an aid to debugging  interpreted  LISP
functions, which allows rapid turnaround in the `test-edit-test' loop
of debugging.  It is famous for the two functions  FILEIN  and  EDFUN
which behave as follows.

(FILEIN . "FILENAME-LIST")

	The  way  in  which this function takes its arguments differs
only from DSKIN in that all files must come from the user's own  disk
area.
	When a file is loaded with FILEIN, information is  saved  for
each  function defined in the file telling what file it came from and
on what page and line it was defined.    Initially,  this  information
will  only  be saved for atoms which are defined to be EXPRS, FEXPRS,
or MACROS.   If the user wishes to  have  it  saved  for  some  other
property,  for  example VALUES, he can achieve this effect by putting
the property SWAPIT on the property list of the indicator  he  wished
to  have  so  honored, in this case by putting the property SWAPIT on
the property list of the indicator VALUE.

(EDFUN "FUN" "PROP") 

	This function is used in the environment created  by  FILEIN.
It will call in the system editor, SOS, with its attention focused on
the function FUN.  At the same time, it  will  save  a  copy  of  the
user's  LISP  and  prepare for a quick return to this copy.  Once the
editor has been started the function definition may be edited in  the
usual  way.   It should be noted, however, that although edits may be
made to other parts of the file, only the definition of FUN  will  be
loaded on return to LISP.
	If FUN has more that one property for which file  information
is  being  saved, it may be necessary to use the second argument PROP
of EDFUN in order to specify which one is desired.
	When editing has been finished, and a return to LISP 	is
wanted, it is only necessary to type the command G to SOS.   A  saved
copy  of  the  user's  LISP  will  be started and the single function
definition which is modified will be reloaded.
	As long as no global modifications are made to the file, this
process may be repeated indefinitely.  Such  actions  as  renumbering
the file are discouraged, however.
SAILON 28.7                    APPENDIX L                         L-1

                             APPENDIX L

            SOME DIFFERENCES BETWEEN THIS AND OTHER LISPS

                         by Whitfield Diffie

1)   The top level of this system does not use EVALQUOTE as do many
systems.  However, EVALQUOTE may be defined as follows:

     (DE EVALQUOTE NIL
         (PROG NIL
	 L     (TERPRI)
	       (PRINT (EVAL (CONS (READ) (MAPCAR
		    (FUNCTION (LAMBDA (X) (LIST (QUOTE QUOTE) X)))
		    (READ)))))
	       (GO L)))

     The top level of LISP 1.6 is equivalent to:

               (PROG NIL
	       L     (TERPRI)
		     (PRINT (EVAL (READ)))
		     (GO L))


2) The order of the arguments in the various functions 
   MAP, MAPCAR etc. is function first, list second, 
   rather that the reverse as in many systems.  

3) There are certain differences even between Stanford 
   Lisp and other DEC system Lisps.  

	a) the comment character is ascii 32 

	b) project programmer numbers are pairwords 
	   in which each half holds up to three 
	   right adjusted sixbit characters.  

	c) The new debugging package depends on system 
	   features only available in the Stanford system.  
	   This debugging package is described in Appendix K.

SAILON 28.7                    APPENDIX M                         M-1

                             APPENDIX M

                       LISP Display Primitives


                            by Lynn Quam

	A set of display primitives are now available for LISP users.
These primitives use the features in the  D.  Poole  display  service
subsystem.   Users  should  be familiar with section II.D.8 of Sailon
55, and SAILON 29.

	The following display primitives  allow  the  user  to  enter
display  commands  into "the" current display buffer. The contents of
this  buffer  are  not  seen  until  the  user  executes  the  "SHOW"
primitive.


(AIVECT X Y)	draws an absolute invisible vector to (X,Y).
(AVECT X Y)	draws an absolute visible vector to (X,Y).
(APT X Y)	draws an endpoint vector to (X,Y).

(RIVECT X Y)	draws a relative invisible vector to (X,Y).
(RVECT X Y)	draws a relative visible vector to (X,Y).
(RPT X Y)	draws a relative endpoint vector to (X,Y).

(GVECT X Y OP SIZE BRT)	assembles display processor opcode <OP>
		with X, Y, SIZE, BRT fields specified.  
		E.g., (GVECT 0 0 46 1 0) draws a zero length
		invisible vector and sets the character size to 1.

(LOCATE)	returns the position of the last word put
		in the display buffer.

(DJUMP N)	stores a display processor jump to location n.
(DJSR N)	stores a display processor subroutine call to
		location n.

(FIXUP X Y)	stores y into the jump (or JSR) address at 
		location x.

All of the above commands return the referred to display buffer
address.

(SHOW N)	the current display buffer is displayed on 
		"piece of glass" (N).

(KILL N)	erases "piece of glass" (N).
(CLEAR)		erases the current display buffer.

(DTYOS)		selects the display buffer for character
		output from LISP. (TYO, PRINT, ETC.)







SAILON 28.7                    APPENDIX M                         M-2

(DTYOU)		unselects character output to the display buffer.

DTYOS and DTYOU make it possible to define a printing function:
(DE DPRINC (L) (PROG NIL (DTYOS) (PRINC L) (DTYOU) (RETURN L)))

(CHINIT CHSIZ LINELENGTH LEFTMARGIN)
	initializes internal parameters for DTYOS so that
	text will be displayed with size <CHSIZE> and with 
	line length and left margin specified.

To use these primitives, use the following loading sequence:

	(INC(INPUT SYS: (LISPDP.LSP)))
	<sequence of output>
	(LOAD <NIL or T>)
	*SYS:LISPDP$
	<loader output>
	*(DISPINIT)
	<now you can use the display>

SAILON 28.7                    APPENDIX N                         N-1

			APPENDIX N

			   TRACE

		by Lynn Quam and Whitfield Diffie

I.  FUNCTIONS FOR DEBUGGING FUNCTIONS

	Three different types of debugging aids are available: TRACE,
TRACET and BREAK.

A)  TRACE  and its auxiliary functions UNTRACE and RESET allow one to
monitor the entrance to and exit from "traced"  functions.  (Warning:
use  (NOUUO  T)  with compiled functions) when a "traced" function is
entered.
	(ENTERING  <recursion  depth>  <function  name>)  <values  of
arguments> is typed.  When exited,
	(LEAVING  <recursion  depth>  <function  name>)  <result>  is
typed.

(TRACE <list of names>) FEXPR causes all functions in list of names
	to be "traced".  TRACE returns a list of names of those
	functions which were previously not traced.

(UNTRACE <list of names>) FEXPR is the inverse to TRACE, i.e., it
	restores each function to its previous untraced state.

(RESET) EXPR causes all recursion depth counters to be reset to
	zero.  Only necessary when a traced function is abnormally
	exited.

B) TRACET and its auxiliary functions UNTRACET SLST and  USLST  allow
one  to  monitor  all  SET's or SETQ's to atoms selected for by SLST.
When such a SET or SETQ occurs,

	SET <atom name> <value>) or
	SETQ <atom name> <value>)

is printed.  (Warning - use (NOUUO T) with compiled functions)

(TRACET) EXPR turns on SET-SETQ monitoring.

(UNTRACET) EXPR turns off SET-SETQ monitoring.

(SLST <list of atoms>) FEXPR appends <list of atoms> to the list of
	monitored atoms.

(USLST <list of atoms> removes each atom from list of monitored
	atoms.

SAILON 28.7                    APPENDIX N                         N-2

C) (BREAK <comment> <expression>) FEXPR is useful for observing
	the state of variable bindings within lambda expressions
	and progs.  When BREAK is entered, (BREAK . <comment>)
	is printed.  BREAK then enters a READ-EVAL-PRINT loop
	until an atom which is the value of the atom  *BPROCEED* 
	is typed to READ.  This atom will initially be P>, but may
	be changed by setting the value of *BPROCEED*.  BREAK then 
	exits with <value>.
SAILON 28.7                    APPENDIX O                         O-1

			APPENDIX O

			   SMILE

		by Lynn Quam and Whitfield Diffie


I.  FUNCTIONS FOR USING OUTPUT DEVICES

(LPT) EXPR is used to start an output file on the line printer.
 It does

		(PROG NIL (OUTC (OUTPUT LPT:) T)
			(LINELENGTH LPTLENGTH)
			(OUTTIME))
		where OUTTIME prints a heading, time and date.

(OFF) EXPR is used to end an output file.  It does

		(PROG NIL (PRINT T)
			  (OUTC NIL T)
			  (LINELENGTH TTYLENGTH))

(LPTOUT <expr-list>) FEXPR is used to create an entire output 
file on the lineprinter.  It does

		(PROG NIL (LPT)
			  (MAPC (FUNCTION EVAL) <expr-list>)
			  (OFF))

		Examples: (LPTOUT (GRINL ALLFNS))
			  (LPTOUT (PRINT OBLIST)  (PRINT FOO))

(DSKOUT <file name> <expr-list>)  FEXPR is used to create an
	entire output file on disk file DSK: <file-name>.LSP.
	It sets linelength to LPTLENGTH, and evaluates all
	expressions in <expr-list>, then does (OFF).

		Example:  (DSKOUT NEWFNS (GRINL NEWFNS))


II.  OTHER USEFUL FUNCTIONS

(GRINL <atom>) FEXPR causes all atoms in the list (<atom>
 <value of atom>)  to be GRINDEFed.

For example, (GRINL ALLFNS) will cause ALLFNS and every function 
which has been defined by DE, DF, or DM to be GRINDEFed.

	GRINDEF uses the auxiliary functions SPRINT, HUNOZ, PANL,
and PPOS.
SAILON 28.7                    APPENDIX O                         O-2

(GETDEF <device name> <file name> <list of function names>)  
	FEXPR needs selected function definitions from
	specified disk file, and prints the names of
	those found.  GETDEF returns ***.

		Example:  (GETDEF DSK:  NEWFNS SIZE FOOBAZ)

(TIMER <expression list>) FEXPR returns the execution time                
		in milliseconds of the expressions in the
		expression list.

                Example:  (TIMER (GC) (GC)) returns the number
		of milliseconds necessary to do 2 garbage
		collections.

(EDIT <atom> <old> <new>) FEXPR causes all occurrences of <old>
		s-expression to be replaced by <new> s-expression
		in some property of <atom>.  The property to
		change is selected as follows:

		(1)  EXPR
		(2)  FEXPR
		(3)  first property on property list.

		Example:  (EDIT OFF TTYLENGTH 105)
		Would charge OFF to:
		(DEFPROP OFF
		(LAMBDA NIL (PROG NIL (PRINT T) (OUTC NIL T)
		(LINELENGTH 105))) EXPR)

		EDIT returns T if a change was made.  Otherwise NIL.

SAILON 28.7                    APPENDIX P                         P-1

                             APPENDIX P

             CONSTRUCTION OF A LISP DISK-DECTAPE SYSTEM

                            by Lynn Quam and Whitfield Diffie


LIST OF FILES, TYPES AND DESTINATIONS

FILES		TYPE				DESTINATION

LISP.MAC	MACRO		STEPS 2,5	LISP.DMP

LOADER.MAC	MACRO		STEPS 3,5	LISP.LOD	

SYMMAK.MAC	MACRO		STEPS 4,5	LISP.SYM

ALVINE.MAC	MACRO		STEP 6		LISP.ED

LISP.LSP	LISP		STEP 5		LISP.LSP	

COMPLR		LISP		STEPS 8,9	COMPLR.CMP

LAP		LISP		STEP 5		LAP	

SMILE		LISP		STEP 5		SMILE

GRIN		LISP		STEP 5		GRIN

TRACE		LISP		STEP 5		TRACE


	DISK  				DECTAPE  

					The following conventions
					     will be made:

					DTAS = dectape where system
          				     will be created

					DTAI = dectape where source          
					     files are

					DTAT = dectape for temporary      
					     files

					Also, make the following            
					     assignment:

					.ASSIGN DTAS:  DSK:

SAILON 28.7                    APPENDIX P                         P-2

1) Assemble with MACRO-10 

	LISP.REL←LISP.MAC 		DTAT:LISP.REL←DTAI:LISP.MAC 

	LOADER.REL←LOADER.MAC 		DTAT:LOADER.REL←DTAI:LOADER.MAC 

	SYMMAK.REL←SYMMAK.MAC 		DTAT:SYMMAK.REL←DTAI:SYMMAK.MAC 

	ALVINE.REL←ALVINE.MAC		DTAT:ALVINE.REL←DTAI:ALVINE.MAC 


2) To generate the LISP INTERPRETER 

.R LOADER<cr>

	*LISP<alt>			*DTAT:LISP<alt>

↑C 

	.SAVE DSK:LISP 10<cr>		.SAVE DTAS:LISP 10<cr>


3) To generate the LISP LOADER 

.R LOADER<cr>

	*LOADER<alt>			*DTAT:LOADER<alt>

↑C 

.START<cr>

<This creates the mode 17 file DSK:LISP.LOD or DTAS:LISP.LOD> 


4) To generate the LISP LOADER SYMBOL TABLE 

.R LOADER<cr>

	*DSK:LISP/J,DSK:SYMMAK<alt>	*DTAT:LISP/J,DTAT:SYMMAK<alt>

↑C 

.START<cr>

<This creates the file DSK:LISP.SYM> or <DTAT:LISP.SYM>

5) Copy to DSK or DTAS the following files: 

LISP.LSP, SMILE, GRIN, TRACE, and LAP 

Now if using DECTAPE do: .ASSIGN DTAS: SYS: 
SAILON 28.7                    APPENDIX P                         P-3

6)  To generate ALVINE

.R LISP<cr>

ALLOC? N

	(DSKIN (ALVINE.LSP))<cr>	*(DSKIN DTAI: (ALVINE.LSP))<cr>

	* (LOAD)<cr>			* (LOAD)<cr>

	* ALVINE <alt>			* DTAT: ALVINE <alt>

* (GETSYM SUBR ALVINE)<cr>

* (ALVINE)<cr>

<This creates the file DSK: LISP.ED> or <DTAS: LISP.ED>

	Copy the file LISP.ED to SYS

7)  To compile the LISP compiler:

7a)  If there is an older revision of the compiler, do

.R COMPLR<cr>

and go to step 8.

7b)  If there is not an older version of the compiler, do

.R LISP 34<cr>

ALLOC? N

	*(DSKIN COMPLR)<cr>		*(DSKIN DTAI: COMPLR)<cr>

<this loads everything>

and go to step 8.

8)  Actual compilation of the LISP COMPILER

					* (SETQ INDEV (QUOTE DTAI:))<cr>

					* (SETQ OUTDEV (QUOTE DTAT:))<cr>

* (COMPL COMPLR)<cr>

	<random messages>               

↑C
SAILON 28.7                    APPENDIX P                         P-4

<This generates the file DSK: COMPLR.LAP> or <DTAT: COMPLR.LAP>.

9)  To load the compiled LISP COMPILER,

.R LISP 30<cr>

ALLOC? Y
FULL. WDS=3000<sp>
BIN.PROG.SP=14300<sp>
SPEC.PDL=<sp>
REG. PDL=<sp>
HASH=475<sp>

	*(DSKIN (COMPLR.LAP))<cr>	*(DSKIN DTAT: (COMPLR.LAP))<cr>

* (CINIT)<cr>

↑C

	.SAVE DSK: COMPLR<cr>		.SAVE DTAS: COMPLR<cr>
	
	Copy the file COMPLR.DMP to SYS:

SAILON 28.7                    REFERENCES                       REF-1

                             REFERENCES

1.  John McCarthy, et al., LISP 1.5 Programmer's Manual
	(Cambridge, Mass., MIT Press, 1962).

2.  Clark Weissman, LISP 1.5 Primer, (Dickenson Publishing
	Co., 1967).

3.  Robert A. Saunders, "LISP - On the Programming System",
	in Edmond C. Berkley and Daniel G. Bobrow (eds.),
	The Programming Language LISP:  Its Operation and
	Applications, 2nd edition, (Cambridge, Mass., The
	MIT Press, 1966), p.54.

SAILON 28.7                      INDEX                          IND-1

			INDEX


ABS          SUBR    . . . . . . . . . . . . . . . . 12-1
ADD1         SUBR    . . . . . . . . . . . . . . . . 12-1
ALIST                . . . . . . . . . . . . . . . .  7-3
AND          FSUBR   . . . . . . . . . . . . . . . .  9-3
APPEND       LSUBR   n arguments . . . . . . . . . . 10-1
APPLY        LSUBR   . . . . . . . . . . . . . . . .  7-1
ARG          SUBR    . . . . . . . . . . . . . . . .  6-2
ARRAY        FSUBR   different . . . . . . . . . . . 15-1
ASCII        SUBR    . . . . . . . . . . . . . . . . 11-3
ASSOC        SUBR    uses EQ . . . . . . . . . . . . 10-6
ATOM         SUBR    . . . . . . . . . . . . . .  3-1,9-1
BAKGAG       SUBR    initialized to T  . . . . . . . 16-1
BASE         VALUE   initialized to 8  . . . . . . .  4-1
BIGNUM		     . . . . . . . . . . . . . . .  I,4-2
BOOLE        LSUBR   . . . . . . . . . . . . . . . . 12-3
BPEND        VALUE   top of binary program space . .  C-3
BPORG        VALUE   bottom of binary program space.  C-4
BREAK	     FEXPR   . . . . . . . . . . . . . . . .  N-2
CAR          SUBR    . . . . . . . . . . . . . . . . 10-2
CDR          SUBR    . . . . . . . . . . . . . . . . 10-2
...          ...     . . . . . . . . . . . . . . . .
CAAAAR       SUBR    . . . . . . . . . . . . . . . . 10-2
CDDDDR       SUBR    . . . . . . . . . . . . . . . . 10-2
CHRCT        SUBR    . . . . . . . . . . . . . . . . 14-5
COND         FSUBR   allows more than one consequent  8-1
CONS         SUBR    . . . . . . . . . . . . . . . . 10-1
CSYM         FSUBR   . . . . . . . . . . . . . . . . 11-3
DDTIN        SUBR    . . . . . . . . . . . . . . . . 14-3
DDTOUT       SUBR    . . . . . . . . . . . . . . . . 14-5
DE           FSUBR   . . . . . . . . . . . . . . . . 11-2
DEFPROP      FSUBR   . . . . . . . . . . . . . . . . 11-2
DEPOSIT      SUBR    . . . . . . . . . . . . . . . . 15-2
DF           FSUBR   . . . . . . . . . . . . . . . . 11-2
DIFFERENCE   MACRO   n arguments . . . . . . . . . . 12-1
DIVIDE       SUBR    . . . . . . . . . . . . . . . . 12-1
DM           FSUBR   . . . . . . . . . . . . . . . . 11-2
DSKIN        FEXPR   . . . . . . . . . . . . . . . .14-2a
ED           SUBR    . . . . . . . . . . . . . . . .  A-1
EDFUN        FEXPR   . . . . . . . . . . . . . . . .  K-1
EQ           SUBR    . . . . . . . . . . . . . . . .  9-1
EQUAL        SUBR    . . . . . . . . . . . . . . . .  9-1
ERR          SUBR    . . . . . . . . . . . . . . . . 16-1
ERRSET       FSUBR   . . . . . . . . . . . . . . . . 16-1
EVAL         LSUBR   second argument allowed . . . .  7-1
EXAMINE      SUBR    . . . . . . . . . . . . . . . . 15-2
EXARRAY      FSUBR   . . . . . . . . . . . . . . . . 15-2
EXCISE       SUBR    . . . . . . . . . . . . . . . .  H-1
EXPLODE      SUBR    . . . . . . . . . . . . . . . . 10-7
EXPLODEC     SUBR    . . . . . . . . . . . . . . . . 10-7
SAILON 28.7                      INDEX                          IND-2

EXPR                 . . . . . . . . . . . . . . . .  6-2
FEXPR                . . . . . . . . . . . . . . . .  6-2
FILEIN       FEXPR   . . . . . . . . . . . . . . . .  K-1
FILENAMES	     . . . . . . . . . . . . . . . . 14-1
FIX          SUBR    . . . . . . . . . . . . . . . . 12-2
FIX1A        SYM     . . . . . . . . . . . . . . . .  E-2
FIXNUM               . . . . . . . . . . . . . . . .  4-2
FLATSIZE     SUBR    . . . . . . . . . . . . . . . . 10-7
FLONUM               . . . . . . . . . . . . . . . .  4-3
FORCE        SUBR    . . . . . . . . . . . . . . . . 14-5
FSUBR                . . . . . . . . . . . . . . . .  E-4
FUNARG               . . . . . . . . . . . . . . . .  7-4
FUNCTION     FSUBR   . . . . . . . . . . . . . . . .  7-1
FUNCTIONAL ARGUMENTS   . . . . . . . . . . . . . . .  7-1
GC           SUBR    . . . . . . . . . . . . . . . .  D-1
GCD          SUBR    . . . . . . . . . . . . . . . . 12-1
GCGAG        SUBR    . . . . . . . . . . . . . . . .  D-1
GCTIME       SUBR    . . . . . . . . . . . . . . . .  D-1
GENSYM       SUBR    . . . . . . . . . . . . . . . . 11-3
GET          SUBR    . . . . . . . . . . . . . . . . 11-1
GETL         SUBR    . . . . . . . . . . . . . . . . 11-1
GETSYM       FEXPR   . . . . . . . . . . . . . . . .  H-1
GO           FSUBR   . . . . . . . . . . . . . . . . 13-1
GREATERP     MACRO   n arguments . . . . . . . . . .  9-3
GRINDEF      FSUBR   . . . . . . . . . . . . . . . .  A-1
IBASE        VALUE   initialized to 8  . . . . . . .  4-1
IDENTIFIER	     . . . . . . . . . . . . . . . .  3-1
INC          SUBR    . . . . . . . . . . . . . . . . 14-2
INITFN       SUBR    . . . . . . . . . . . . . . . . 16-1
INPUT        FSUBR   . . . . . . . . . . . . . . . . 14-1
INTEGER		     . . . . . . . . . . . . . . . .  4-1
INTERN       SUBR    . . . . . . . . . . . . . . . . 11-2
LABEL                . . . . . . . . . . . . . . . .  6-1
LAMBDA               . . . . . . . . . . . . . . . .  6-1
LAST         SUBR    returns end of list . . . . . . 10-2
LENGTH       SUBR    . . . . . . . . . . . . . . . . 10-4
LESSP        MACRO   n arguments . . . . . . . . . .  9-3
LEXPR		     . . . . . . . . . . . . . . . .  6-2
LINELENGTH   SUBR    . . . . . . . . . . . . . . . . 14-5
LIST         FSUBR   . . . . . . . . . . . . . . . . 10-1
LOAD         SUBR    . . . . . . . . . . . . . . . .  H-1
LSH          SUBR    . . . . . . . . . . . . . . . . 12-3
LSUBR                . . . . . . . . . . . . . . . .  E-4
MACRO                . . . . . . . . . . . . . . . .  6-3
MAKNAM       SUBR    . . . . . . . . . . . . . . . . 10-7
MAKNUM       SUBR    . . . . . . . . . . . . . . . .  E-2
MAP          SUBR    different argument order. . . . 10-5
MAPC         SUBR        "        "       "    . . . 10-5
MAPCAR       SUBR        "        "       "    . . . 10-6
MAPLIST      SUBR        "        "       "    . . . 10-5
MEMBER       SUBR    uses EQUAL  . . . . . . . . . .  9-2
MEMQ         SUBR    uses EQ . . . . . . . . . . . .  9-2
SAILON 28.7                      INDEX                          IND-3

MINUS        SUBR    . . . . . . . . . . . . . . . . 12-1
MINUSP       SUBR    . . . . . . . . . . . . . . . .  9-2
NCONC        LSUBR   . . . . . . . . . . . . . . . . 10-3
NCONS        SUBR    . . . . . . . . . . . . . . . . 10-1
NIL          VALUE   initialized to NIL  . . . . . .  5-1
NOT          SUBR    . . . . . . . . . . . . . . . .  9-3
NOUUO        SUBR    initialized to T  . . . . . . .  E-3
NULL         SUBR    . . . . . . . . . . . . . . . .  9-2
NUMBER		     . . . . . . . . . . . . . . . .  4-1
NUMBERP      SUBR    . . . . . . . . . . . . . . . .  9-2
NUMVAL       SUBR    . . . . . . . . . . . . . . . .  E-2
OBLIST       VALUE   . . . . . . . . . . . . . . . .  3-3
OR           FSUBR   . . . . . . . . . . . . . . . .  9-3
OUTC         SUBR    . . . . . . . . . . . . . . . . 14-4
OUTPUT       FSUBR   . . . . . . . . . . . . . . . . 14-4
PGLINE       SUBR    . . . . . . . . . . . . . . . . 14-2
PLUS         MACRO   n arguments . . . . . . . . . . 12-1
PNAME                . . . . . . . . . . . . . . . .  3-2
PRIN1        SUBR    allows non-atomic S-expressions 14-5
PRINC        SUBR    . . . . . . . . . . . . . . . . 14-5
PRINT        SUBR    TERPRI first  . . . . . . . . . 14-6
PROG         FSUBR   . . . . . . . . . . . . . . . . 13-1
PROG2        SUBR    allows up to 5 arguments. . . . 13-1
PROPERTY LIST	     . . . . . . . . . . . . . . . .  3-2
PUTPROP      SUBR    order of arguments different    11-1
PUTSYM       FEXPR   . . . . . . . . . . . . . . . .  H-2
QUOTE        FSUBR   . . . . . . . . . . . . . . . .  7-1
QUOTIENT     MACRO   n arguments . . . . . . . . . . 12-1
READ         SUBR    . . . . . . . . . . . . . . . . 14-3
READCH       SUBR    . . . . . . . . . . . . . . . . 14-4
READLIST     SUBR    . . . . . . . . . . . . . . . . 10-7
REMAINDER    SUBR    . . . . . . . . . . . . . . . . 12-1
REMOB        FSUBR   . . . . . . . . . . . . . . . . 11-2
REMPROP      SUBR    . . . . . . . . . . . . . . . . 11-1
RESET        EXPR    . . . . . . . . . . . . . . . .
RETURN       SUBR    . . . . . . . . . . . . . . . . 13-1
REVERSE      SUBR    . . . . . . . . . . . . . . . . 10-4
RPLACA       SUBR    . . . . . . . . . . . . . . . . 10-3
RPLACD       SUBR    . . . . . . . . . . . . . . . . 10-3
SASSOC       SUBR    uses EQ . . . . . . . . . . . . 10-6
SET          SUBR    . . . . . . . . . . . . . . . . 11-2
SETARG       SUBR    . . . . . . . . . . . . . . . .  6-3
SETQ         FSUBR   . . . . . . . . . . . . . . . . 11-2
SEXPRESSION	     . . . . . . . . . . . . . . . .  5-1
SPEAK        SUBR    . . . . . . . . . . . . . . . .  D-1
SPECBIND     SYM     . . . . . . . . . . . . . . . .  E-2
SPECSTR      SYM     . . . . . . . . . . . . . . . .  E-2
SPECIAL		     not in interpreter  . . . . . .  F-1
SPECIAL VARIABLES    . . . . . . . . . . . . . . . .  7-3
SPRINT       SUBR    . . . . . . . . . . . . . . . .  A-1
STORE        FSUBR   . . . . . . . . . . . . . . . . 15-2
STRING               . . . . . . . . . . . . . . . .  3-3
SAILON 28.7                      INDEX                          IND-4

SUB1         SUBR    . . . . . . . . . . . . . . . . 12-1
SUBR                 . . . . . . . . . . . . . . . .  E-3
SUBST        SUBR    . . . . . . . . . . . . . . . . 10-4
T            VALUE   initialized to T  . . . . . . .  9-1
TERPRI       SUBR    . . . . . . . . . . . . . . . . 14-6
TIME         SUBR    . . . . . . . . . . . . . . . . 16-1
TIMES        MACRO   n arguments . . . . . . . . . . 12-1
TRACE        FEXPR   . . . . . . . . . . . . . . . .  N-1
TRACET       EXPR    . . . . . . . . . . . . . . . .  N-1
TYI          SUBR    . . . . . . . . . . . . . . . . 14-4
TYO          SUBR    . . . . . . . . . . . . . . . . 14-6
VALUE                . . . . . . . . . . . . . . . .  3-2
VARIABLE BINDINGS    . . . . . . . . . . . . . . . .  7-2
XCONS        SUBR    . . . . . . . . . . . . . . . . 10-1
ZEROP        SUBR    . . . . . . . . . . . . . . . .  9-2

$EOF$                . . . . . . . . . . . . . . . . 14-2
*AMAKE       SYM     . . . . . . . . . . . . . . . .  E-4
*APPEND      SUBR    . . . . . . . . . . . . . . . . 10-1
*DIF         SUBR    . . . . . . . . . . . . . . . . 12-1
*EVAL        SUBR    . . . . . . . . . . . . . . . .  7-1
*EXPAND      SUBR    . . . . . . . . . . . . . . . .  6-4
*EXPAND1     SUBR    . . . . . . . . . . . . . . . .  6-4
*FUNCTION    FSUBR   . . . . . . . . . . . . . . . .  7-4
*GETSYM      SUBR    . . . . . . . . . . . . . . . .  H-1
*GREAT       SUBR    . . . . . . . . . . . . . . . .  9-3
*LCALL       SYM     . . . . . . . . . . . . . . . .  E-4
*LESS        SUBR    . . . . . . . . . . . . . . . .  9-3
*NOPOINT     VALUE   initialized to NIL  . . . . . .  4-1
*PLUS        SUBR    . . . . . . . . . . . . . . . . 12-1
*PUTSYM      SUBR    . . . . . . . . . . . . . . . .  H-2
*QUO         SUBR    . . . . . . . . . . . . . . . . 12-1
*RSET        SUBR    initialized to NIL  . . . . . . 16-1
*TIMES       SUBR    . . . . . . . . . . . . . . . . 12-1